393 lines
20 KiB
Markdown
393 lines
20 KiB
Markdown
# DTF System - Project Context for AI Agents
|
|
|
|
## Purpose of this document
|
|
|
|
Read this document before changing code, documentation, architecture, or scope.
|
|
It is the current English source of truth for the project. It supersedes older
|
|
decisions in `README.md`, `ESPECIFICACAO.md`, `schema.sql`, and the existing
|
|
prototype code whenever they conflict.
|
|
|
|
Update this file whenever the team makes a material product, process, or
|
|
architecture decision.
|
|
|
|
## Project goal
|
|
|
|
Build a DTF ordering and production-flow system for Dropstar/Altus.
|
|
|
|
The current process is slow and manual: customers send artwork through
|
|
WhatsApp, staff forward files, designers discover problems late, and production
|
|
status is not visible outside the factory. The business has substantially more
|
|
machine capacity than it currently uses. The goal is to let customers place DTF
|
|
orders online, pay, send artwork, and follow production without making
|
|
WhatsApp, shared folders, or manual handoffs the bottleneck.
|
|
|
|
The customer-facing value is speed and clarity. The operations value is a
|
|
traceable queue and fewer lost or manually handled orders.
|
|
|
|
## Current MVP scope
|
|
|
|
The MVP must be delivered in **at most three weeks**. The target is a working
|
|
online system, not factory-machine automation.
|
|
|
|
### Included
|
|
|
|
- Dedicated DTF site/subdomain.
|
|
- Existing Site DTF commercial rules and product experience.
|
|
- Direct, resumable multipart file upload to Cloudflare R2.
|
|
- Mercado Pago payment integration with signed and idempotent webhooks.
|
|
- Freight quotation and charging at checkout.
|
|
- Idempotent Tiny/Olist order integration and order traceability.
|
|
- Online Kanban for production status and secure file download.
|
|
- WhatsApp status notifications.
|
|
- Private object storage, 30-day file retention, backups, and basic security.
|
|
- Operator guidance for the factory team.
|
|
|
|
### Explicitly outside the three-week delivery
|
|
|
|
- Automatic pre-flight validation. It will be validated after delivery using
|
|
real customer files and real printed output, then refined as support work.
|
|
- Direct FlexiPRINT integration.
|
|
- Factory-side agent, hot folder, internal file server automation, VPN, and
|
|
heartbeat monitoring.
|
|
- Production-room dashboard, printer/machine telemetry, and advanced reports.
|
|
- Automated shipping-label purchase, shipping-label printing, and dispatch
|
|
automation. The MVP freight scope is quote selection and charging only.
|
|
- Personalized cart behaviour based on past orders, day, or time.
|
|
|
|
After delivery, the team provides support and evaluates requested changes. Do
|
|
not turn post-delivery support into a new committed delivery phase without an
|
|
explicit decision.
|
|
|
|
## Agreed production model
|
|
|
|
```text
|
|
Customer browser
|
|
-> Site DTF / API on VPS
|
|
-> direct multipart upload to private Cloudflare R2
|
|
-> Mercado Pago payment + freight selected at checkout
|
|
-> Tiny/Olist order record
|
|
-> online Kanban
|
|
-> factory operator downloads final file and imports it manually into FlexiPRINT
|
|
```
|
|
|
|
WhatsApp is a notification channel, not the artwork-upload channel. It is used
|
|
for payment confirmation, correction requests, production status, and order
|
|
completion.
|
|
|
|
The operator works through the browser. The factory does not need an installed
|
|
agent or an internal server for the MVP.
|
|
|
|
If the factory internet connection fails, only the factory team temporarily
|
|
loses access to the Kanban and secure downloads. The public portal, payments,
|
|
uploads, R2 objects, queue, and cloud services remain online. Factory work
|
|
resumes when local access returns.
|
|
|
|
## Infrastructure and deployment
|
|
|
|
- **VPS:** runs the website, API, worker, PostgreSQL, ClamAV, Kanban, and
|
|
third-party integrations.
|
|
- **Cloudflare R2:** private S3-compatible object storage for original uploads
|
|
and final files. It does not run the application, database, worker, or
|
|
antivirus.
|
|
- **Upload path:** the browser uploads directly to R2 using short-lived,
|
|
server-issued presigned multipart URLs. Large files must never be proxied
|
|
through the VPS.
|
|
- **Deployment:** one Portainer-owned `dtf-cloud` Docker Swarm stack. One Gitea
|
|
Actions workflow tests/scans, publishes `latest` plus commit-SHA application
|
|
images, and calls the Portainer webhook. Activation remains blocked pending
|
|
the production work listed below.
|
|
- **Recommended VPS baseline:** 4 vCPU, 16 GB RAM, and 200 GB NVMe. Existing
|
|
VPS capacity may be used if it safely meets or exceeds this baseline.
|
|
- **Backups:** PostgreSQL backups go to R2. Application secrets are never
|
|
committed to Git.
|
|
|
|
## File retention
|
|
|
|
The business does not want an unlimited artwork library.
|
|
|
|
| Artifact | Retention |
|
|
|---|---:|
|
|
| Incomplete multipart upload | 1 day |
|
|
| Rejected or infected upload | 3 days |
|
|
| Customer original after approval | Up to 7 days |
|
|
| Final print artwork | Maximum 30 days from the first upload |
|
|
| Order history and metrics | Kept in the database without keeping the image |
|
|
|
|
The 30-day retention decision overrides older references to 90 days or
|
|
12-month artwork reordering.
|
|
|
|
## R2 planning cost reference
|
|
|
|
R2 cost is driven primarily by the average number of gigabytes stored during a
|
|
month; read/write operations are expected to be a much smaller cost at the
|
|
project's scale. There is no egress charge in the current planning model.
|
|
|
|
The client-facing roadmap uses the following planning examples, based on
|
|
standard R2 storage pricing, the included storage allowance, and an exchange
|
|
rate reference of USD 1 = BRL 5.13:
|
|
|
|
| Average storage | Approx. R2/month | Approx. BRL/month |
|
|
|---|---:|---:|
|
|
| 100 GB | USD 1.35 | BRL 7 |
|
|
| 500 GB | USD 7.35 | BRL 38 |
|
|
| 1 TB | USD 14.85 | BRL 76 |
|
|
| 3 TB | USD 44.85 | BRL 230 |
|
|
|
|
These are planning estimates only. Confirm Cloudflare pricing, exchange rates,
|
|
taxes, and payment-provider fees before presenting a commercial quote.
|
|
|
|
## Commercial rules
|
|
|
|
The existing rules in `dtf-site.html` are approved as the current source of
|
|
truth. Do **not** redesign, simplify, or change prices, discounts, minimums,
|
|
rounding, or product modes without explicit approval.
|
|
|
|
The current site contains four product modes, quality-based price tiers,
|
|
artwork-ready discounts, separate assembly charges for loose artwork, a
|
|
one-metre minimum, and ten-centimetre billing rounding.
|
|
|
|
The browser may display the calculation, but production payment creation must
|
|
recalculate and validate all price, quantity, freight, and discount values on
|
|
the server. Client-provided totals are never authoritative.
|
|
|
|
## Freight
|
|
|
|
The original visual freight flow in `dtf-site.html` was a stub with only pickup
|
|
functional. The localhost bridge now supports pickup and backend fake freight
|
|
quotes; there is still no real carrier quotation or production checkout.
|
|
|
|
The customer already uses Correios and other shipping platforms. Before freight
|
|
can be completed, obtain:
|
|
|
|
- The platform(s) that should be used as the source of truth.
|
|
- API credentials or delegated access for the selected platform.
|
|
- Origin postal code/address.
|
|
- Available services and carriers to offer.
|
|
- Packaging weight and dimensions by DTF length/package.
|
|
- Freight business policy: exact pass-through, subsidy, free-shipping rules,
|
|
pickup, or other exceptions.
|
|
|
|
At checkout, the backend must quote freight from the selected source, store the
|
|
chosen service and quoted amount, include the amount in the Mercado Pago
|
|
payment, and persist it in the order. Do not create a payment before the freight
|
|
amount is final.
|
|
|
|
## Integrations
|
|
|
|
### Mercado Pago
|
|
|
|
Required before production payment integration, not for the local mock milestone:
|
|
|
|
- Production credentials.
|
|
- Webhook configuration/access.
|
|
|
|
Webhook processing must verify authenticity and be idempotent. A duplicate or
|
|
late delivery must not create a duplicate payment, order, message, or queue
|
|
card.
|
|
|
|
### Tiny/Olist
|
|
|
|
Tiny/Olist is already available. The implementation must create/update orders
|
|
idempotently and use the order number for traceability. Confirm the actual API
|
|
endpoints, marker/tag behaviour, and rate limits before production use.
|
|
|
|
### WhatsApp
|
|
|
|
WhatsApp is already available, but the technical provider still needs to be
|
|
confirmed (official Meta Cloud API, Z-API, or another provider).
|
|
|
|
Implement only the required customer events:
|
|
|
|
1. Payment approved.
|
|
2. Artwork correction needed, with a secure link back to the site.
|
|
3. Order entered production.
|
|
4. Order ready for collection or shipping.
|
|
|
|
Messages initiated by the business may require approved templates depending on
|
|
the provider and conversation state. Use an outbox/job mechanism with retries,
|
|
delivery status handling, and idempotency. Do not send artwork through
|
|
WhatsApp.
|
|
|
|
## Factory responsibilities after delivery
|
|
|
|
The client/factory team is responsible for:
|
|
|
|
- Opening the Kanban, downloading final files, and importing them manually into
|
|
the current FlexiPRINT setup.
|
|
- Performing real print tests and reporting mismatches in the final file or
|
|
printed result.
|
|
- Maintaining PCs, printers, FlexiPRINT licences, printing profiles, internal
|
|
folders, and the local factory network.
|
|
- Informing the development team about changes to prices, freight, operational
|
|
rules, or external platforms that need system changes.
|
|
|
|
The development team delivers the online system, provides usage guidance, and
|
|
supports subsequent corrections or scoped enhancements.
|
|
|
|
## Three-week roadmap
|
|
|
|
| Week | Delivery | Result |
|
|
|---|---|---|
|
|
| 1 | Infrastructure and upload | VPS, domain, database, R2, multipart upload, antivirus, and service foundation. |
|
|
| 2 | Payment, freight, and order | Mercado Pago, freight quotation, idempotent Tiny/Olist order creation, final file generation, and main Kanban states. |
|
|
| 3 | Kanban and handover | Online Kanban, secure download, WhatsApp status messages, 30-day retention, and operational handover. |
|
|
|
|
## Known implementation status
|
|
|
|
### Active localhost milestone (2026-09-15)
|
|
|
|
The current implementation target is localhost before any production connection.
|
|
Use `compose.yaml`, `.env.example`, and `LOCAL_SETUP.md`. The runtime is in
|
|
`local/`; historical `portal/`, `kanban/`, `agente/`, and `schema.sql` are preserved
|
|
as references and are not imported or started by Compose.
|
|
|
|
- One local `dtf-cloud` Compose project runs seven long-lived services: Site and
|
|
Kanban web gateways, FastAPI Portal/API, PostgreSQL, MinIO, ClamAV, and a
|
|
PostgreSQL outbox/scanning worker. Separate database and storage initialization
|
|
jobs provision restricted runtime identities, for nine Compose services total.
|
|
- MinIO implements the S3 storage boundary with direct multipart browser uploads,
|
|
resumable parts, private objects, and short-lived signed operator downloads.
|
|
- Payment, freight, Tiny/Olist, and WhatsApp use fake adapters only. No production
|
|
credentials or integrations are configured. The API and worker have no external
|
|
network route; only local web/storage gateways publish loopback ports.
|
|
- The original Site commercial calculation and appearance remain the source of
|
|
truth. Its existing browser artwork analysis is retained as prototype advice;
|
|
no new automatic pre-flight, server artwork analysis, or print-file generation
|
|
is implemented or invoked.
|
|
- Since client length and grade could be tampered with and automatic pre-flight
|
|
is deferred, a local operator manually confirms those commercial inputs before
|
|
checkout. This is a development trust-boundary decision, not a new production
|
|
promise. The backend calculates all tiers, discounts, assembly-inclusive rates,
|
|
one-metre minimum, ten-centimetre rounding, freight, and final totals. Immutable
|
|
approved quotes expire after 24 hours. A customer confirms the server total
|
|
on the Site to create one idempotent local paid order.
|
|
- Paid orders use `rec`, `tra`, `fil`, `imp`, `cor`, `fin`, with allowed transitions,
|
|
operator authentication, concurrency checks, and durable movement history.
|
|
Local mock integration receipts are visible in the Kanban.
|
|
- The customer portal at `/portal.html` supports local registration/login,
|
|
stronger scrypt password hashing with legacy-hash upgrade, revocable HttpOnly
|
|
sessions, owned order history/status, secure active
|
|
file downloads, and correction uploads. Registration/login can claim only the
|
|
current guest session's records, never orders found by email or CNPJ. Email
|
|
verification and password recovery are not implemented.
|
|
- Unfinished carts (including File blobs) recover from IndexedDB for 24 hours in
|
|
the same browser, scoped to the guest/account identity. Recovered items can be
|
|
removed/replaced or joined by new items; in-place reconstruction of the artwork
|
|
editor and cross-device cart synchronization are not implemented. Browser
|
|
storage capacity limits apply. Payment clears the saved cart. Logout revokes
|
|
the server session and clears local checkout metadata and saved File blobs
|
|
across open Site tabs.
|
|
- Operators manually upload and approve a complete final-file set, with one or
|
|
more files per order item. Queue entry requires active final files for every
|
|
item. Corrections invalidate the old set; customers submit corrections through
|
|
their portal, and operators reapprove final files. No artwork transformation,
|
|
automatic pre-flight, or machine control is performed.
|
|
- Every completed upload is quarantined pending a local ClamAV scan. Only `clean`
|
|
files can be quoted, commercially approved, paid, downloaded, attached as final
|
|
files, or admitted to the print queue. Rejected/error files remain blocked and
|
|
expire within three days. The isolated scanner uses signatures bundled in its
|
|
pinned image and has no external network route. The transport accepts files up
|
|
to 5 GiB, but the local scan/release limit is 128 MiB; larger files remain
|
|
blocked. This malware gate is not print pre-flight or artwork validation.
|
|
- A retention worker removes expired object bytes but keeps order/file metadata:
|
|
incomplete uploads after one day, originals within seven days of manual final
|
|
artwork approval, and attached final/correction files within 30 days of the
|
|
order's first upload. Storage lifecycle is also a 30-day backstop.
|
|
- Structured security events are written to logs and PostgreSQL. The local
|
|
`security_status` command summarizes authentication, rate-limit, scan, and
|
|
scanner/signature alerts without exposing secrets. Security regression tests,
|
|
exact-runtime Python dependency auditing, and Trivy image reports live under
|
|
`local/` and `output/security/`; open findings are documented in
|
|
`SECURITY_REPORT.md` and are not a production-readiness claim.
|
|
- All direct and transitive Python packages are pinned with artifact hashes in
|
|
`local/requirements.lock`; the API image build requires those hashes. The lock
|
|
is regenerated in a disposable Python 3.12 container by
|
|
`local/lock_dependencies.sh`. A fresh exact-runtime audit found no known Python
|
|
advisories on 2026-09-15; this does not cover OS/container findings.
|
|
- `compose.staging.yaml` is a separate, network-disabled readiness gate only. It
|
|
validates non-secret staging decisions and rejects placeholders, local endpoints,
|
|
fake providers, embedded secret settings, and unsafe secret sources. It does not
|
|
deploy the application, contain credentials, or contact any real provider.
|
|
- A separate production delivery package now exists under `deploy/`, with
|
|
non-root API/web image definitions, a single Portainer Docker Swarm stack,
|
|
external secret/volume contracts, health-monitored rolling updates,
|
|
commit-SHA rollback images, and one protected Gitea workflow under
|
|
`.gitea/workflows/`. The package never contains provider credentials and has
|
|
not been deployed. Its fail-closed preflight intentionally rejects the current
|
|
source until production adapters, Docker-secret file loading, approved inputs,
|
|
restore rehearsal, image scans, and human security approval are complete.
|
|
- `python3 -m local.backup create-and-verify` creates a private, Git-ignored bundle
|
|
containing a PostgreSQL dump plus every complete, unexpired object already marked
|
|
`clean`. SHA-256 manifests protect both parts. Verification restores the database
|
|
under a UUID name and the object bytes under a UUID MinIO prefix, hashes the
|
|
restored bytes, then removes only those temporary targets. Active data is never
|
|
overwritten; pending, rejected, errored, expired, and purged objects are excluded.
|
|
Run this local snapshot while uploads and retention are idle. Scheduling, offsite
|
|
copies, and production restore operations remain unfinished.
|
|
- Real providers, production authentication hardening, email verification/recovery,
|
|
automatic final-file generation, production backup operations, and production
|
|
activation remain incomplete. Deployment plumbing exists but cannot pass its
|
|
release gate yet. No factory automation or pre-flight is added.
|
|
|
|
See `IMPLEMENTATION_REPORT.md` for verification, `PRODUCTION_INPUTS.md` for the
|
|
decisions and evidence required before staging or production connection, and
|
|
`PORTAINER.md` for the production delivery contract.
|
|
The client roadmap promises are unchanged, so its PDF source is not regenerated
|
|
for this local implementation checkpoint.
|
|
|
|
### Existing assets
|
|
|
|
- `dtf-site.html`: rich static front-end prototype. It includes the current
|
|
commercial rules, client-side artwork analysis, current-session cart, and
|
|
delivery UI. The localhost checkout bridge connects it to the new local API.
|
|
- `portal/`: early FastAPI prototype for the original Tiny-first, token-link
|
|
upload flow.
|
|
- `kanban/`: early FastAPI/SQLite Kanban prototype.
|
|
- `agente/`: factory-side agent prototype; out of current MVP scope.
|
|
- `tmp/pdfs/generate_dtf_report.py`: generator for the current client-facing
|
|
roadmap PDF.
|
|
- `output/pdf/dtf-plano-producao-e-roadmap.pdf`: current generated roadmap.
|
|
- `Reunião iniciada às 2026_09_09 09_39 GMT-03_00 - Anotações do Gemini.pdf`:
|
|
meeting notes that established the business direction. Treat it as context;
|
|
the latest decisions in this document define the active scope.
|
|
|
|
### Important gaps and stale assumptions
|
|
|
|
- The original Site had no backend payment, freight quote, order persistence,
|
|
authentication, purchase history, or real cart persistence. Local order
|
|
persistence, reviewed quotes, mock freight and fake payment now work through
|
|
`local/static/checkout.js`. The local customer portal now provides accounts and
|
|
order history; cart recovery is browser-local. Production account verification,
|
|
recovery, and cross-device cart editing are still absent.
|
|
- Without the local bridge, the original freight fallback remains a stub.
|
|
Real freight quotation remains unimplemented in all runtimes.
|
|
- The existing `portal/whats.py` and `kanban/whats.py` are duplicated and send
|
|
direct text messages. They are not production-ready notification modules.
|
|
- Older documentation and code describe a Tiny webhook creating an upload link,
|
|
a factory agent, local Kanban, FlexiPRINT automation, 90-day retention, and
|
|
12-month artwork reuse. Those are not the current MVP model.
|
|
|
|
## Documentation synchronization
|
|
|
|
`context.md` is the compact operating context for agents. The current
|
|
client-facing narrative, diagrams, and formatting live in
|
|
`output/pdf/dtf-plano-producao-e-roadmap.pdf`, generated from
|
|
`tmp/pdfs/generate_dtf_report.py`.
|
|
|
|
When a decision changes, update both the relevant implementation context here
|
|
and the roadmap source when it changes what the client-facing plan promises.
|
|
|
|
## Change-control rules for agents
|
|
|
|
- Preserve the current Site DTF commercial rules unless explicitly asked to
|
|
change them.
|
|
- Do not add factory-side automation, a local agent, hot folders, FlexiPRINT
|
|
control, machine dashboards, or a new post-MVP delivery commitment by
|
|
inference.
|
|
- Do not claim that R2 hosts or executes application services.
|
|
- Keep all customer-facing and internal documentation in English only when this
|
|
file is the requested artifact; otherwise follow the user's requested
|
|
language.
|
|
- When a requirement is unclear, distinguish between the MVP, a future
|
|
enhancement, and an existing prototype assumption before changing code.
|