Add comprehensive quote management and UI improvements: - Add `email_received_at` field to quotes collection, TypeScript types, and setup script - Update quote attachments schema to mark `kind` optional for legacy attachments, add `uploaded_at` field, and improve documentation comments - Create `/api/v1/users/lookup` server endpoint to resolve user IDs to display names - Add stable user ID → color mapping for visual grouping of claimed quotes - Enhance quotes list page: reorder tab filters, show claimer names, color-code rows per claimant - Update quote detail page to display claimer info with user icon - Expand DataTable component to support per-row custom class and style props - Overhaul QuoteEmailCard: add proper HTML/plain text body sanitization/linkification, inline PDF/image previews, improved metadata display, and fixed auth-aware attachment previews via blob URLs
177 lines
6.6 KiB
JSON
177 lines
6.6 KiB
JSON
{
|
|
"_comment_top": "WFDASH — PocketBase schema snippet for the quote_attachments collection. This collection backs the v5 Catch and Create attachment upload pipeline. Import via Settings → Import collections in the PB admin UI. The collection id (pbc_quote_attachments_NEW) is a placeholder — PB will assign its own 15-char id on import; if you need to pin it, replace it after import and update all workflow HTTP URLs that reference /api/collections/quote_attachments/records/.",
|
|
"collections": [
|
|
{
|
|
"_comment": "quote_attachments — one row per uploaded file. quote is OPTIONAL so the Catch and Create pipeline can POST the file BEFORE the quote record exists; a downstream PATCH links them.",
|
|
"id": "pbc_quote_attachments_NEW",
|
|
"name": "quote_attachments",
|
|
"type": "base",
|
|
"listRule": "@request.auth.id != ''",
|
|
"viewRule": "@request.auth.id != ''",
|
|
"createRule": "@request.auth.id != ''",
|
|
"updateRule": "@request.auth.id != ''",
|
|
"deleteRule": "@request.auth.id != ''",
|
|
"fields": [
|
|
{
|
|
"autogeneratePattern": "[a-z0-9]{15}",
|
|
"hidden": false,
|
|
"id": "text_qa_id",
|
|
"max": 15,
|
|
"min": 15,
|
|
"name": "id",
|
|
"pattern": "^[a-z0-9]+$",
|
|
"presentable": false,
|
|
"primaryKey": true,
|
|
"required": true,
|
|
"system": true,
|
|
"type": "text"
|
|
},
|
|
{
|
|
"hidden": false,
|
|
"id": "autodate_qa_created",
|
|
"name": "created",
|
|
"onCreate": true,
|
|
"onUpdate": false,
|
|
"presentable": false,
|
|
"system": true,
|
|
"type": "autodate"
|
|
},
|
|
{
|
|
"hidden": false,
|
|
"id": "autodate_qa_updated",
|
|
"name": "updated",
|
|
"onCreate": true,
|
|
"onUpdate": true,
|
|
"presentable": false,
|
|
"system": true,
|
|
"type": "autodate"
|
|
},
|
|
{
|
|
"_comment": "The actual file. multipart upload via PocketBase's standard file field. Allowed mime types omitted — set them to whatever your RFQ vendors send (pdf, png, jpg, docx, csv, xlsx, etc).",
|
|
"hidden": false,
|
|
"id": "file_qa_file",
|
|
"maxSelect": 1,
|
|
"maxSize": 52428800,
|
|
"mimeTypes": ["application/pdf", "image/png", "image/jpeg", "image/webp", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "text/csv", "text/plain", "application/json", "application/octet-stream"],
|
|
"name": "file",
|
|
"presentable": false,
|
|
"protected": false,
|
|
"required": false,
|
|
"system": false,
|
|
"thumbs": null,
|
|
"type": "file"
|
|
},
|
|
{
|
|
"_comment": "Link to the quote this attachment belongs to. Optional — populated AFTER the quote record is created, via the PATCH Attachment (set quote) step in v5.",
|
|
"cascadeDelete": false,
|
|
"collectionId": "pbc_2527524235",
|
|
"hidden": false,
|
|
"id": "relation_qa_quote",
|
|
"maxSelect": 1,
|
|
"minSelect": 0,
|
|
"name": "quote",
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "relation"
|
|
},
|
|
{
|
|
"_comment": "Email Message-ID. Part of the unique composite index so re-firing the workflow on the same email (e.g. retry, IMAP re-poll) doesn't upload duplicates.",
|
|
"autogeneratePattern": "",
|
|
"hidden": false,
|
|
"id": "text_qa_message_id",
|
|
"max": 0,
|
|
"min": 0,
|
|
"name": "email_message_id",
|
|
"pattern": "",
|
|
"presentable": false,
|
|
"primaryKey": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "text"
|
|
},
|
|
{
|
|
"autogeneratePattern": "",
|
|
"hidden": false,
|
|
"id": "text_qa_filename",
|
|
"max": 0,
|
|
"min": 0,
|
|
"name": "filename",
|
|
"pattern": "",
|
|
"presentable": true,
|
|
"primaryKey": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "text"
|
|
},
|
|
{
|
|
"autogeneratePattern": "",
|
|
"hidden": false,
|
|
"id": "text_qa_content_type",
|
|
"max": 0,
|
|
"min": 0,
|
|
"name": "content_type",
|
|
"pattern": "",
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "text"
|
|
},
|
|
{
|
|
"hidden": false,
|
|
"id": "number_qa_size",
|
|
"max": null,
|
|
"min": null,
|
|
"name": "size_bytes",
|
|
"onlyInt": true,
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "number"
|
|
},
|
|
{
|
|
"_comment": "pdf / image / doc / other — convenience classification so the dashboard can render appropriate previews without sniffing the file. Required by docs/pocketbase/quote_attachments.collection.json but treated as optional here because attachments uploaded before the v7 multi-attachment workflow wrote `kind` (none of them have it). The v7 workflow now writes `kind`; old rows can be backfilled via the dashboard or a one-shot PB rule.",
|
|
"hidden": false,
|
|
"id": "select_qa_kind",
|
|
"maxSelect": 0,
|
|
"name": "kind",
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "select",
|
|
"values": ["pdf", "image", "doc", "other"]
|
|
},
|
|
{
|
|
"hidden": false,
|
|
"id": "date_qa_uploaded",
|
|
"max": "",
|
|
"min": "",
|
|
"name": "uploaded_at",
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "date"
|
|
},
|
|
{
|
|
"_comment": "Provenance. Which n8n workflow uploaded this. Lets you tell apart v4 / v5 / manual uploads in the dashboard.",
|
|
"autogeneratePattern": "",
|
|
"hidden": false,
|
|
"id": "text_qa_uploaded_by",
|
|
"max": 0,
|
|
"min": 0,
|
|
"name": "uploaded_by",
|
|
"pattern": "",
|
|
"presentable": false,
|
|
"required": false,
|
|
"system": false,
|
|
"type": "text"
|
|
}
|
|
],
|
|
"indexes": [
|
|
"CREATE UNIQUE INDEX `idx_qa_msg_filename` ON `quote_attachments` (`email_message_id`, `filename`) WHERE `email_message_id` != '' AND `filename` != ''",
|
|
"CREATE INDEX `idx_qa_quote` ON `quote_attachments` (`quote`)"
|
|
],
|
|
"system": false
|
|
}
|
|
]
|
|
}
|