> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tangoanalytics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Badge inbound

# Tango Space Badge Inbound — File

> Generated from `Tango Space Badge Inbound Integration Design Specification V0.4.docx` in SharePoint folder `01 Common Integrations`.
> OAS spec: [`badge-inbound.yaml`](./badge-inbound.yaml)

## Overview

SFTP file-based inbound. Client drops a pipe-delimited file of badge (access-control) events to Tango's SFTP server. Tango upserts records keyed on `person_id` (Employee ID); never deletes badge data.

**Owner:** Tango Analytics
**Spec version:** 0.4
**Status:** Draft (auto-generated — needs review)

## Transport

| Attribute | Value | |
| - | - | - |
| Direction | Inbound (Client → Tango) | |
| Mechanism | SFTP file drop | |
| File format | Pipe-delimited (\` | `) text, `.txt\` |
| File naming | `{CLIENTCODE}_BADGE_MMDDYYYYHHMMSS.txt` | |
| Production host | `sftp.tangoanalytics.com` | |
| Test host | `sftpdev.tangoanalytics.com` | |
| Path | `/inbound/badge` | |
| Auth | SFTP user/password (TBD) | |
| Frequency | TBD | |

## Integration logic

* Add/update only — Tango never deletes badge data.
* `person_id` (Employee ID) is the unique key for matching/creating records.
* Daily incremental file: client sends only records that have changes.
* If no updates → no file. If file is empty/header-only → service log notes `no data sent in the file`.
* If a person has multiple events at the same location, Tango processes the **first listed** event (no chronological resolution).
* Visitor IDs flow through the same `person_id` field — Tango recommends prefixing with `V-`.

## Data fields (required ✅)

| Field | Type | Req | Sample | Notes |
| - | - | - | - | - |
| `client_id` | VARCHAR | ✅ | `324` | Static per client — same value on every row |
| `person_id` | VARCHAR | ✅ | `12345` | Employee or visitor ID; unique key |
| `entry_type` | VARCHAR | ✅ | `EMPLOYEE` | Lookup: `EMPLOYEE` / `VISITOR` |
| `building_id` | VARCHAR | ✅ | `ABC` | Must match a Building ID in Tango |
| `badge_type` | VARCHAR | ✅ | `ENTRY` | Lookup: `ENTRY` / `EXIT` |
| `event_type` | VARCHAR | – | `Granted Access` | |
| `asset_number` | VARCHAR | – | `123456` | Optional — used if reader is loaded as an asset |
| `reader_number` | VARCHAR | – | `SD Ground / N Main Entry Door` | |
| `event_date` | DATETIME | ✅ | `6/21/2021 00:00:00` | `MM/DD/YYYY HH:MM:SS` |

## Validations

| Condition | Error message |
| - | - |
| `building_id` missing/invalid | `Fatal Error: Building ID is not present` / `Building ID <> is invalid for Employee ID <>` |
| `badge_type` missing/invalid | `Fatal Error: Badge Type <> is Invalid for Employee ID <>` |
| `client_id` missing | `Fatal Error: Client ID <> is not present` |
| `event_date` missing/invalid | `Fatal Error: Date/Time <> is not in valid format` |
| `person_id` missing/invalid | `Fatal Error: Employee ID <> is Invalid for Building ID <>` |
| `entry_type` missing/invalid | `Fatal Error: Entry Type is invalid for Employee ID <>` |

## Open Questions / Assumptions

* [ ] **SFTP credentials** are `<TBD>`.
* [ ] **Timing/frequency** is `<TBD>`.
* [ ] **Event type allowed values** are not enumerated; sample shows `Granted Access` only.
* [ ] **Multi-event-per-person ordering**: stated as "first listed" — confirm that's intended (vs. last-listed or chronological).
* [ ] **`event_date` interpretation**: doc shows `6/21/2021 0:00` and also `MM/DD/YYYY 00:00:00` — assumes 24-hour clock, padded seconds.

## Changelog

| Ver | Date | Description | Author |
| - | - | - | - |
| 0.1 | 07/09/2022 | Initial Draft | Jasmin Thasleem |
| 0.2 | 10/2/2023 | Reformatted | Michael Phoenix |
| 0.3 | 11/13/2023 | Updated validations & reformatted | Jasmin Thasleem |
| 0.4 | 07/31/2024 | Updated Process, File Naming, Integration Logic | Rahma Ouedraogo |
