diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 6d88686..a93b14b 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -145,7 +145,7 @@ jobs: fs --scanners secret --exit-code 1 --severity HIGH,CRITICAL \ --no-progress /src - # PORTAINER.md described this as blocking publication. It never ran at + # docs/PORTAINER.md described this as blocking publication. It never ran at # all, and turning it on unconditionally would block every deploy: the # source preflight refuses a release while the payment and messaging # adapters are fake, which is the deliberate state the stack runs in diff --git a/README.md b/README.md index bbc959f..4a6c46f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Sistema DTF 24h — Altus Group -> **Active local milestone (2026-09-11):** Read [CONTEXT.md](CONTEXT.md) first. +> **Active local milestone (2026-09-11):** Read [docs/CONTEXT.md](docs/CONTEXT.md) first. > Start with `docker compose up --build`, then open the [Site](http://localhost:8080) > and [Kanban](http://localhost:8081). Optional configuration: copy `.env.example` -> to `.env`. Follow [LOCAL_SETUP.md](LOCAL_SETUP.md) for the complete test flow, +> to `.env`. Follow [docs/LOCAL_SETUP.md](docs/LOCAL_SETUP.md) for the complete test flow, > local login, health checks, and troubleshooting. See -> [IMPLEMENTATION_REPORT.md](IMPLEMENTATION_REPORT.md) for scope and reuse decisions. -> Production delivery uses one Portainer stack; see [PORTAINER.md](PORTAINER.md). +> [IMPLEMENTATION_REPORT.md](docs/historico/IMPLEMENTATION_REPORT.md) for scope and reuse decisions. +> Production delivery uses one Portainer stack; see [docs/PORTAINER.md](docs/PORTAINER.md). > Everything below is preserved historical prototype documentation, not the active > setup or delivery specification. Do not run its production integrations or agent. @@ -20,8 +20,8 @@ > `schema.sql`, `.env.exemplo`) no longer exists, and the model it describes is > not the one implemented. Kept for the business reasoning in it — the capacity > figures, the cost argument, the meeting decisions. For how the system actually -> works read [CONTEXT.md](CONTEXT.md); for what is outstanding read -> [ROADMAP.md](ROADMAP.md); for the original documents see +> works read [docs/CONTEXT.md](docs/CONTEXT.md); for what is outstanding read +> [docs/ROADMAP.md](docs/ROADMAP.md); for the original documents see > [docs/historico/](docs/historico/README.md). --- diff --git a/app/core/secrets.py b/app/core/secrets.py index ffdcb91..55b6c21 100644 --- a/app/core/secrets.py +++ b/app/core/secrets.py @@ -3,7 +3,7 @@ Swarm mounts each secret as a file and the stack passes its path as `_FILE`. The deployed `docker-compose.yml` passes credentials as plain environment variables, so this module is inert there. It exists so a stack can supply them as -Docker secrets instead without any code change; see `ROADMAP.md` 2.12. +Docker secrets instead without any code change; see `docs/ROADMAP.md` 2.12. Call `load()` in every entrypoint before any configuration is read. diff --git a/deploy/PRODUCTION_CHECKLIST.md b/deploy/PRODUCTION_CHECKLIST.md index f2df6ee..969820e 100644 --- a/deploy/PRODUCTION_CHECKLIST.md +++ b/deploy/PRODUCTION_CHECKLIST.md @@ -5,7 +5,7 @@ substitute for `production_preflight.py`, CI, staging acceptance, or change appr ## Application and external contracts -- [ ] `PRODUCTION_INPUTS.md` has owners, decisions, and evidence for every item. +- [ ] `docs/PRODUCTION_INPUTS.md` has owners, decisions, and evidence for every item. - [ ] Production R2, freight, Mercado Pago, Tiny/Olist, and WhatsApp adapters have sandbox contract tests and least-privilege credentials. - [ ] Payment webhook authenticity, replay handling, and idempotency are tested. diff --git a/CONTEXT.md b/docs/CONTEXT.md similarity index 98% rename from CONTEXT.md rename to docs/CONTEXT.md index ca6bf0c..fb3bafd 100644 --- a/CONTEXT.md +++ b/docs/CONTEXT.md @@ -141,7 +141,7 @@ 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 +The existing rules in `web/index.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. @@ -163,7 +163,7 @@ image dimensions alone must never classify a normal artwork as a finished sheet. ## Freight -The original visual freight flow in `dtf-site.html` was a stub with only pickup +The original visual freight flow in `web/index.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. @@ -313,7 +313,7 @@ as references and are not imported or started by Compose. - All direct and transitive Python packages are pinned with artifact hashes in `infra/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 + `infra/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, @@ -373,7 +373,7 @@ referenced them; recover from Git history if ever needed. 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 +- The existing the removed prototypes duplicated WhatsApp senders 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 diff --git a/LOCAL_SETUP.md b/docs/LOCAL_SETUP.md similarity index 100% rename from LOCAL_SETUP.md rename to docs/LOCAL_SETUP.md diff --git a/PORTAINER.md b/docs/PORTAINER.md similarity index 93% rename from PORTAINER.md rename to docs/PORTAINER.md index 3cb7f79..2796739 100644 --- a/PORTAINER.md +++ b/docs/PORTAINER.md @@ -5,12 +5,11 @@ prebuilt images, pushes them to the Gitea registry, and calls one Portainer webhook. Portainer owns and redeploys one Docker Swarm stack named `dtf-cloud`. The deployed stack is the repository's `docker-compose.yml`, which the -`dtf-cloud` Portainer stack points at. `deploy/stack.yaml` is a more hardened -definition that supplies every credential as a Docker secret rather than an -environment variable; it is not currently deployed. See `ROADMAP.md` 2.12 before -assuming either is authoritative. +`dtf-cloud` Portainer stack points at. It was once accompanied by `deploy/stack.yaml`, a more hardened definition +supplying credentials as Docker secrets; that file was removed in favour of one +definition. See `ROADMAP.md` 2.12 for the reasoning and what remains open. -`deploy/stack.yaml` contains Site, Kanban, API, +The stack contains Site, Kanban, API, worker, PostgreSQL, ClamAV, and a one-time database initializer. Production uses Cloudflare R2, so MinIO is not part of this stack. @@ -94,7 +93,8 @@ In Portainer select **Stacks → Add stack → Git repository**: - Name: `dtf-cloud` - Repository: this Gitea repository - Reference: `main` -- Compose path: `deploy/stack.yaml` +- Compose path: `docker-compose.yml` (the repository default, which is what the + existing `dtf-cloud` stack uses; it must stay at the root for this reason) - Registry: the private `gitea.blyzer.com.br` registry - Re-pull image: enabled - Automatic update: webhook diff --git a/PRODUCTION_INPUTS.md b/docs/PRODUCTION_INPUTS.md similarity index 100% rename from PRODUCTION_INPUTS.md rename to docs/PRODUCTION_INPUTS.md diff --git a/ROADMAP.md b/docs/ROADMAP.md similarity index 99% rename from ROADMAP.md rename to docs/ROADMAP.md index 3337b40..a40af5b 100644 --- a/ROADMAP.md +++ b/docs/ROADMAP.md @@ -12,6 +12,11 @@ client inputs (1.1, 1.2, 2.10). Block 1 still waits on client inputs for 1.1/1.2. +> Paths in closed items are written as they were when the finding was made. +> The repository was laid out by role on 2026-09-21 (`local/` became `app/`, +> with `tests/`, `ops/`, `infra/` and `web/` beside it); the history is left +> as recorded rather than rewritten. + **Last audit:** 2026-09-18, full read of `app/`, `dtf-site.html`, `deploy/`, `.gitea/`, docs and legacy prototypes. Findings below carry their audit IDs. diff --git a/SECURITY_REPORT.md b/docs/SECURITY_REPORT.md similarity index 100% rename from SECURITY_REPORT.md rename to docs/SECURITY_REPORT.md diff --git a/staging/README.md b/staging/README.md index d1cc439..31c0df8 100644 --- a/staging/README.md +++ b/staging/README.md @@ -2,9 +2,9 @@ This directory does not contain a staging deployment and does not authorize any real integration. It provides a separate, network-disabled validation root for -the non-secret decisions in `PRODUCTION_INPUTS.md`. +the non-secret decisions in `docs/PRODUCTION_INPUTS.md`. -1. Complete the business and technical decisions in `PRODUCTION_INPUTS.md`. +1. Complete the business and technical decisions in `docs/PRODUCTION_INPUTS.md`. 2. Copy `staging.env.example` to `staging.env` and replace the `TBD` values with non-secret metadata only. `staging.env` is ignored by Git and Docker builds. 3. Run: