feat-auto-attributes
New Features
Auto-attributes (Phase 1 — metadata-only)
Documents deposited by automatic services (Tower, future agents) now carry autoAttributes — structured metadata separate from manual user attributes. Smart lists ("Listes Automatiques") filter documents dynamically by attribute codes.
Reference documentation: docs/auto-attributes.md — folder filters, configuration model, platform API, dashboard setup. Update this doc when behaviour changes.
Schema changes:
documents.autoAttributes[]— new field{code, value}[], separate fromdocuments.attributes[](manual, unchanged)companies.folders[].type—'manual' | 'auto'(default'manual')companies.folders[].targetAttributeCodes[]— OR filter by code (any value)companies.folders[].targetAutoAttributes[]— AND filter by{code, value}pairscompanies.folders[].displayedCodes[]— codes displayed per document in list viewattributes.code?— optional stable identifier for global attributes (companyRef: null)agent_codes— new collection:agentName,allowedAttributeRefs[](resolved from global catalogue)auto_folder_templates— global smart-list templates cloned into company foldersapitokens.agent?— optional field linking an API token to a registered agent (managed via Retool)
API changes:
POST /documents— universal ingestion endpoint. Supports manual (attributes) and auto (autoAttributes) metadata. Bearer auth with optionalBcyip-Agent/Bcyip-Version/Bcyip-Platformheaders. Strict validation against agent catalogue. Technical codesbcyip:agentandbcyip:agent-versionauto-injected (not configurable on agents).GET /documents— response extended with top-levelautoAttributes: AutoAttributesCount[]and per-documentautoAttributes[]GET /documents— supportsX-Mock: trueheader for front-first developmentGET/POST/PATCH/DELETE /platform/agents— ingestion agents; body usesallowedCodes[](catalogue codes, resolved to refs server-side)GET/POST/PATCH/DELETE /platform/auto-attribute-codes— global auto code catalogueGET/POST/PATCH/DELETE /platform/folder-templates— smart-list templatesGET/POST/PATCH/PUT /platform/companies/:id/*— cross-company ops (folders, attributes, label overrides) viaX-Platform-Admin-TokenGET /platform/companies/:id/users/agents— per-useragentsruntime map for ops dashboard
Auto-attribute codes:
- Cross-cutting:
source-type,source-name - Domain namespaces:
git_repo,git_commit,git_branch,git_tag,ftp_source-path(_separator;:reserved forbcyip:*) - Technical codes with
bcyip:prefix —bcyip:agent,bcyip:agent-version(server-injected only) - Ingestion normalizes legacy
bcyip-agent/ unprefixed businessbcyip:*during transition
User agent runtime:
users.agents— map keyed by agent name (iptower,ipmagicbox, …); neo updates on auto depositsusers.agent— legacy IP Magic Box field; backend still updates for dashboardGET /api/admin/users
Resolver:
FolderV0.TOWER— union Tower v1 (tags: bcyip-tower) + any agent deposit (bcyip:agentinautoAttributes, any value)hasMultipleDocsTypes/GET /documents/should-display-folders— sameisTowerdetection for Magic Box v0 tab bar (IP MagicBox / IP Tower)- Custom auto folders — dynamic filter via
targetAutoAttributesortargetAttributeCodes(see reference doc)
Catalogue LOV (value labels):
- Global auto codes support
lov: [{ value, label }](legacystring[]normalized on read) allowExtraValues/allowMultipleValuesexposed on platform CRUD (defaultallowExtraValues: truefor auto)GET /documentsadds optionalvalueLabelonautoAttributes[]and filter value counts — additive, current IP Magic Box ignores itGET /platform/auto-attribute-codesreturnslov+lovValues(canonical strings for backward compat)- Ingestion never rejects values outside
lov(manual or auto)
Bootstrap: global catalogue and agents are managed via /platform/auto-attribute-codes and /platform/agents (no seed scripts in repo).
Planned (not in this release): GET /platform/auto-attribute-codes/:code/observed-values — distinct deposited values per code for the ops label editor (see reference doc).
Agent ingest with legacy file upload (n8n / Airtable)
Goal: Let external automation upload a binary via the legacy files API, then create the neo document with autoAttributes in a second call — same pattern as Tower without coupling upload to documentId.
Solution: POST /documents accepts optional fileId (validated remotefiles row: same hash, same job, not already linked). Pipeline uses fileSize from the linked file when omitted.
Features:
- Two-step flow:
POST /api/files/upload/→POST /api/v2/documentswithhash,fileId,autoAttributes, agent token +Bcyip-Agent - OpenAPI documents
fileIdon the ingest body
Files Modified:
src/domains/document/document.controller.ts— optionalfileIdon ingest DTOsrc/domains/document/document.service.ts—resolveLinkedRemoteFile, link on createsrc/domains/document/templates/documents.ts—fileSizefallback fromfileId.size
🐛 Bug Fixes
Idempotent ingest merges autoAttributes and links file
Goal: Retrying the same hash + jobRef (e.g. n8n replay) must not fail when fileId is sent again or when new autoAttributes arrive on retry.
Solution: On idempotent match, merge autoAttributes by code (incoming wins), set fileId only when absent, leave manual fields untouched.
Files Modified:
src/domains/document/document.service.ts—applyIdempotentDocumentUpdates
Automatic hall includes all agent deposits (not only iptower)
Goal: Documents deposited by any registered agent (n8n, future agents) must appear in folder=tower and trigger the Magic Box v0 tab bar when mixed with manual docs.
Solution: Match any bcyip:agent in autoAttributes (not only value: iptower) in buildDocumentFolderFilter and documentsTypeTemplate / isTower.
Files Modified:
src/domains/document/templates/documents.ts—FolderV0.TOWERfiltersrc/domains/document/templates/initialValues.ts—isToweraggregationsrc/domains/document/document.service.ts—hasMultipleDocsTypescommentdocs/auto-attributes.md— folder filter, v0/v1 UI mapping,fileId+ idempotent ingest
Improvements
Tower code naming alignment (docs + OpenAPI examples)
Goal: Keep neo documentation, release notes, and Scalar mock responses aligned with Tower v2 deposit codes (git_*, ftp_source-path) after dropping legacy ref / sha.
Solution: Update the canonical guide, platform agent Swagger examples, and GET /documents mock payload so ops and front devs see the same vocabulary as production deposits.
Files Modified:
docs/auto-attributes.md— taxonomy, folder filter examples, Tower codes table.unreleased/feat-auto-attributes.md— code list in fragmentsrc/domains/document/document.controller.ts—MOCK_RESPONSEauto-attribute examplessrc/domains/platform/agents/agents.types.ts—allowedCodesOpenAPI examples