digidem / digidem/comapeo-cloud-app
spec(cases/reports): evidence-grounded agency reports for Brazil v1
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 29
Description
spec(cases/reports): evidence-grounded agency report workflow for Brazil v1
Status: implementation-ready specification
Summary
Introduce a first-class Cases workflow for turning selected CoMapeo project data into evidence-grounded, agency-specific reports. A Case is the durable project-scoped workspace. Reports are immutable/versioned outputs derived from that Case for a particular recipient agency.
Brazil v1 supports FUNAI, IBAMA, Ministério Público Federal (MPF), and Polícia Federal (PF). Users can create a Case from the Data experience or from the Cases area, select project evidence, review which media and sensitive fields may be disclosed, generate one independent report draft per selected agency, edit the draft manually or with AI/voice assistance, explicitly finalize it, and share/download an A4 PDF plus supporting evidence files.
This is not a generic reporting platform and does not replace CSV/GeoJSON export. Existing/new CSV and GeoJSON workflows remain Exports with no report lifecycle or template semantics.
Product principles
- Case first, report second. A Case can evolve over time and produce multiple agency reports and revisions.
- Human authority. AI drafts and revises; the user reviews, edits, discloses, finalizes, and shares.
- Evidence grounding. Generated factual claims must be traceable to selected Case Facts or explicit user statements. Missing facts are never invented.
- Minimum disclosure. Each agency report receives only the evidence, people, locations, and fields the user approved for that report.
- Immutable finalization. Finalizing a report freezes that report version, evidence snapshot, disclosure decisions, template version, branding, and AI provenance. The Case remains editable.
- Local-first resilience. Case work and manual report editing remain usable without connectivity. AI, remote synchronization, voice transcription, and online sharing require a network.
- No media interpretation in v1. Photos and evidence audio may be included as evidence, but no model transcribes, captions, classifies, or infers from them.
- Provider-agnostic drafting. Cloudflare Workers AI is the default. Users may opt into device-local BYOM provider credentials and select stronger OpenAI-/Anthropic-compatible models.
Goals
- Let users build a project-scoped Case from existing observations, remote detection alerts, tracks, metadata, locations, photos, audio, and user-entered context.
- Support both a single incident and a broader pattern across dates/locations.
- Provide two explicit entry points: Data → Add to case, and Cases → New case → browse/filter evidence.
- Generate separate, recipient-specific report drafts for FUNAI, IBAMA, MPF, and PF from one shared factual Case.
- Make disclosure and provenance review visible before sensitive data leaves the app or a report is finalized.
- Support direct text editing, AI-assisted editing, and spoken editing instructions transcribed with Whisper through Groq.
- Produce professional A4 PDFs with project report branding, selected photos, a disclosure-safe map, evidence references, and an evidence appendix.
- Preserve evidence source references/hashes plus disclosure-safe media derivatives needed to support the finalized report.
- Provide predictable failure, retry, conflict, and revision semantics.
- Keep architecture open for future international agency packs, richer permissions, media understanding, and highly controlled legal analysis.
Non-goals for v1
- Generic user-authored report/template builder.
- Arbitrary external PDF/document upload as Case evidence.
- CSV/GeoJSON as report formats.
- AI image understanding, AI photo captions, evidence-audio transcription, or Indigenous-language media interpretation.
- Autonomous legal findings such as “this constitutes crime X under article Y.”
- Open-web legal research during report generation.
- Automatic submission to government systems.
- Treating email/WhatsApp sharing as proof of official submission.
- Fine-grained Viewer/Contributor/Approver roles before the app has a real user identity/membership model.
- Multi-organization/co-signed report branding.
- Multi-model ensemble/consensus generation in one operation.
- CRDT/realtime collaborative editing.
1. Product vocabulary
Case
A durable, project-scoped workspace containing:
- title;
- primary Case type plus optional secondary Case types;
- lifecycle status;
- user-entered factual context;
- selected evidence references;
- per-evidence media selections;
- optional incident/pattern dates and location summary;
- agency reports and their revisions;
- non-sensitive activity metadata.
Case Facts
A deterministic, structured representation assembled by the application from the Case and approved evidence. AI providers receive Case Facts, not raw project databases or arbitrary CoMapeo JSON.
Case Facts contain stable source IDs and normalized human-readable labels so generated sections can cite provenance.
Agency report
A report for exactly one agency and one template version. Multiple agencies selected in one action produce separate drafts.
Report revision
An immutable sequence boundary. A finalized report is never reopened in place. Changes create a new draft revision.
Template
A curated, versioned, maintainer-owned definition of a recipient-specific report workflow, required/optional facts, section structure, AI constraints, vetted standard/legal language, and official submission guidance.
Evidence bundle
The finalized PDF plus disclosure-safe derivatives of selected supporting media and a manifest linking them to the underlying CoMapeo evidence.
2. Brazil v1 scope
Supported agencies
FUNAI
Focus the report on affected Indigenous people/territory, rights and territorial context, threats or impacts, urgency, supporting evidence, and requested protection/institutional action.
Official submission guidance must be maintained from current FUNAI/Ouvidoria guidance and treated as mutable operational content rather than timeless legal truth.
IBAMA
Focus on environmental damage, location/geometry, chronology, affected resources, supporting observations/media, recurrence, and facts useful for inspection/enforcement.
Ministério Público Federal (MPF)
Produce a fuller factual representation linking chronology, collective/Indigenous/environmental impacts, known involved parties when documented, recurrence/pattern, evidence, and requested institutional measures.
Polícia Federal (PF)
Produce a concise factual communication appropriate to possible federal criminal investigation: what happened, when, where, recurrence, documented actors/vehicles/equipment, and available evidence. Never invent an accused person, intent, offense, or jurisdiction.
Case types
A Case has one primary type and zero or more secondary types.
Territory
- Invasion / illegal occupation
- Territorial encroachment or infrastructure impact
Environment
- Deforestation / illegal logging
- Illegal mining
- Fire
- Illegal hunting / fishing / wildlife exploitation
- Pollution / contamination
People and rights
- Threats / intimidation / violence
- Other violation of Indigenous or territorial rights
Other
- Other / user-defined
Case type guides template selection and drafting but never restricts which evidence or agency the user may choose.
Language
- Brazil templates default to pt-BR.
- The application UI continues to support its existing localized UI languages.
- Report language is a template/output property and is independent of UI locale.
- Voice editing in v1 is intended for mainstream languages supported adequately by the configured Whisper model; this does not imply support for Indigenous-language evidence transcription.
3. User journeys
Entry A — from Data
- User selects one or more selectable project records.
- User chooses Add to case.
- User chooses New case or an existing Case in the same project.
- For a new Case, require only title + primary Case type; project is implicit.
- Added records appear in the Case Evidence workspace.
- User may later return to Data and add more records to the same Case.
The implementation may extend the existing Data selection/filter/map UI rather than creating a parallel selector. Alerts/tracks that live in separate current screens must still be addable through a clear equivalent action and through the Case evidence browser.
Entry B — from Cases
- Primary navigation includes Cases.
- Cases home lists project-scoped Cases with title, primary type, status, updated time, evidence count, and report/revision status summary.
- New case requires title + primary Case type.
- User enters the Case workspace and opens Evidence.
- Evidence browser reuses project search/filter/map concepts to add observations, alerts, and tracks.
Case workspace
Provide clear sections/tabs:
- Overview — title, primary/secondary types, status, user factual context, incident/pattern date/location summaries.
- Evidence — selected records and attachments, list/timeline view, map view, media selection, data-change/unavailable warnings.
- Reports — agency report cards, draft/finalized revisions, Create report.
- Activity — metadata-only history of meaningful Case/report events.
Create reports
- User selects one or more supported agencies.
- The app creates one independent report configuration per agency.
- User can refine evidence/media inclusion and disclosure independently for each report.
- User sees an explicit Information sent for generation summary.
- User selects the model/provider for this operation or uses configured defaults.
- User explicitly approves disclosure for each agency report; a multi-agency review screen may group the work, but each report’s disclosure state remains independently visible and approved.
- Generation may run for multiple agencies, but each is an independent operation and failure boundary.
- Each successful report opens as a separate draft.
Edit report
The user can:
- directly edit report text;
- type an instruction such as “make the timeline clearer”;
- record a spoken editing instruction → Groq Whisper transcript → review/edit transcript → submit instruction → selected report model proposes the revision.
AI never silently mutates the working draft. A validated proposed revision replaces the working revision atomically and is undoable through revision/edit history.
Finalize
Finalization is deliberately separate from generation and sharing:
- review unresolved required information;
- review factual/provenance warnings;
- review disclosure of identities, exact locations, photos, audio, and other sensitive fields;
- review report content;
- user explicitly confirms I have reviewed this report;
- app creates immutable finalized snapshot/artifacts;
- report becomes Finalized.
If changes are needed: Create revision → Draft vN+1 → Finalized vN+1.
Share / submit
Finalization never sends anything automatically.
- Download PDF is always available when the PDF can be rendered.
- Share report uses the platform file share sheet where supported; this may surface WhatsApp, email, or other installed apps.
- PDF + evidence files can be shared/downloaded as supported; fallback is a downloadable evidence bundle archive.
- How to submit shows current official agency channel/instructions and opens the official submission destination when online.
- Never label a report “Submitted” because a file was downloaded, emailed, or shared through WhatsApp.
4. Case data model and lifecycle
Case fields
Required at creation:
idprojectLocalId- remote project namespace when available
titleprimaryTypestatus- timestamps/revision metadata
Optional/progressive:
secondaryTypes[]- factual description/context
- incident date or date range
- user location/territory summary
- people/community/context fields where relevant
- urgency/context fields
Do not require users to manually duplicate values already present in selected evidence.
Case lifecycle
Draft → Active → Closed
- Draft: being assembled.
- Active: ongoing investigation/reporting work.
- Closed: no longer active; data/reports retained.
- Closing does not delete or mutate reports/evidence.
- A closed Case may be reopened if product UX supports it; reopening is an activity event.
Case scope
- A Case belongs to exactly one CoMapeo project in v1.
- Cross-project evidence is not allowed.
- A Case may cover one incident or many related events across locations/dates.
5. Evidence model
Supported record sources
- observations;
- remote detection alerts;
- tracks;
- their normalized fields/tags/metadata;
- coordinates/geometries/timestamps;
- category/preset labels;
- observation photo/audio attachments;
- explicit user-authored Case context.
Evidence reference vs attachment inclusion
Adding a source record to a Case does not automatically disclose all attachments.
For each selected observation attachment, the user explicitly chooses whether the photo/audio belongs in the Case/report evidence set. Report-specific inclusion may further narrow the Case set.
Photos
- Record the original source file/reference and original hash where available, but do not duplicate raw original media into reporting D1/R2 in v1. The raw original remains governed by the underlying CoMapeo project/source and any existing local attachment cache.
- May appear in the PDF appendix if selected for that report.
- Caption is user-authored in v1; AI must not infer/caption photo contents.
- PDF/share derivatives must remove nonessential embedded metadata (including EXIF GPS/device metadata) before external sharing and receive their own derivative hash. The manifest binds original hash → derivative hash without claiming the derivative is the untouched original.
Audio
- Record the original audio source reference/hash where available; reporting storage does not duplicate the raw original media in v1.
- PDF lists it as evidence with stable evidence number, source record, filename/reference and disclosure-safe metadata.
- Any audio file exported in a normal report evidence bundle must be a metadata-scrubbed derivative with its own hash; original raw media is not part of the normal report share bundle.
- If a disclosure-safe derivative cannot be produced, block that media from the external bundle until the user deselects it; never fall back silently to the original.
- No evidence-audio transcription or interpretation in v1.
- Selected evidence audio is distinct from ephemeral microphone audio captured for voice editing.
Stable evidence numbering
A finalized report uses deterministic stable labels such as Evidence 01, Evidence 02, ... and report references/appendix use the same labels. v1 does not add manual reordering: order evidence by its effective event/detection timestamp ascending (fallback to source created timestamp), then by source type and stable source ID as tie-breakers. Finalization freezes that ordered list so PDF regeneration uses the identical numbering.
Source changes in a draft
Store the source record ID and source version (where available) when added/last incorporated.
- Drafts may use the current record content.
- If a source record changed since it was added or since the current report draft was generated, surface Changed since added/generated before finalization.
- Never silently rewrite an already-finalized report.
Deleted/unavailable evidence
- A deleted or unavailable source is never silently removed from a Case/report.
- If a last-known local copy exists, show it as unavailable/deleted and require explicit user confirmation to retain it in a finalized evidence snapshot.
- If the source/media has no usable local or remote content, finalization must require the user to remove/deselect it or restore/download it as appropriate.
- Selected media required by the finalized evidence set must be locally retrievable at finalization; otherwise block finalization for that item with a clear recovery/deselect path.
Unsynced evidence
- Locally available unsynced project evidence can be added to a local Case.
- It is marked as not yet project-synced/portable to other devices.
- Remote Case synchronization must not imply that underlying unsynced CoMapeo evidence has become remotely available.
- Finalization may proceed locally if the complete selected evidence snapshot exists locally; remote artifact status remains pending sync until durable upload succeeds.
6. Disclosure model
Disclosure is per agency report, not global to the Case.
The report disclosure review must allow at minimum:
- reporter identity: include / omit where the relevant channel permits;
- people/witness names: individually include/exclude;
- location: Exact / Area only / Omit;
- photos: individually include/exclude;
- audio: individually include/exclude;
- other sensitive fields: explicit include/exclude when marked sensitive or surfaced by template.
Area only is text-only by default in v1. It strips exact coordinates/geometries from provider payloads, report evidence metadata, and map input, and uses only a user-visible Case/report territory/area/location summary. It must not approximate hidden points by rounding or derive a generalized geometry from them. If an independently existing, user-approved generalized territory/boundary is available, that boundary may be used; otherwise Area-only evidence contributes no map geometry. If no report evidence has Exact geometry and no approved generalized boundary exists, omit the map section rather than blocking finalization.
Before first AI generation for a report, show a concrete disclosure summary, e.g.:
Using 8 observations, 2 alerts, 1 track, case context, dates and approved locations. 2 names are included. 6 photos and 1 audio file are attached as evidence, but media files are not sent to the AI model.
The user explicitly approves this context.
Normal subsequent edits may reuse that approved context. If a later action introduces newly disclosed sensitive evidence/person/location content, require a new disclosure acknowledgement before sending it to an AI provider.
7. Case Facts and AI generation contract
Deterministic Case Facts assembly
The application assembles the report-specific payload before any model call. It must:
- include only the selected/report-approved evidence subset;
- use human-readable field/category labels where available;
- normalize date/location/geometry representations;
- assign stable provenance source IDs;
- apply disclosure transforms before network transmission;
- never include unselected project records;
- never include photo bytes or evidence-audio bytes in v1;
- never include provider credentials in prompts/logs.
Example source identities are conceptual, not a mandated serialization:
observation:<stable-id>alert:<stable-id>track:<stable-id>case-context:<field-or-entry-id>user-statement:<stable-id>
Structured generation result
All provider adapters normalize responses into one internal validated result containing at minimum:
- report title/subject;
- agency/template identity;
- ordered report sections;
- provenance/source references for AI-generated factual sections/claims at a useful section or claim granularity;
- missing-information items;
- warnings/review items.
The app validates the result with Valibot before applying it.
Provider-specific native structured-output capabilities may be used, but the product contract must not depend on one vendor feature. Invalid/malformed output is a failed attempt, not a partial mutation.
Grounding rules
- The model is instructed that supplied Case Facts are the complete factual universe for the report.
- It may reorganize, summarize and professionally phrase those facts.
- It may not invent names, dates, coordinates, causality, intent, legal classification, certainty, or evidence contents.
- It may state that information is unknown/not provided when useful.
- Every returned provenance reference must exist in the submitted Case Facts.
- Unknown source IDs fail validation.
- Source-ID validation proves reference integrity, not semantic truth; human review remains mandatory.
Every report content block/section carries authorship: ai | user. AI blocks carry validated source references. Any direct textual user edit clears all provenance refs on the affected block and sets authorship: user; unaffected blocks retain provenance. A later validated AI rewrite replaces that block with authorship: ai plus newly validated refs. Final PDFs include “Prepared with AI-assisted drafting; content reviewed and finalized by the user.” without exposing provider credentials or pretending provenance proves semantic truth.
Missing information
- Optional missing information does not block generation.
- Surface it in Needs review.
- Truly required template facts may block finalization but should only block initial generation when the template cannot produce a meaningful draft without them.
- Never fill a missing required fact with a guess.
Transactional generation/editing
- Preserve the current draft until a complete model response has been received and validated.
- Persist a local operation record/ID before invoking any provider; apply at most one accepted revision for that operation ID.
- On timeout/network/provider/schema/source-ref failure, leave the current draft untouched.
- A failed agency in a multi-agency action must not roll back successful drafts for other agencies.
- For direct-browser BYOM, idempotency is application-level, not provider-call deduplication: a network retry may incur another provider request/cost, but only one response can be committed for an operation. A tab/browser crash abandons the pending operation; reopening does not silently resubmit it.
- Show retry/change-model/manual-edit actions; an explicit retry creates a new attempt linked to the failed operation.
AI provenance
Record for each accepted AI operation:
- provider class/profile ID (never key);
- model ID;
- operation type (
generate,rewrite, etc.); - timestamp;
- template ID/version;
- relevant disclosure/context fingerprint;
- operation/request ID.
This is internal provenance and need not be printed on the PDF in v1.
8. Agency template model
Templates are built-in, curated, versioned project code/data maintained by CoMapeo Cloud App maintainers.
Do not build an end-user template editor in v1.
A template definition must be typed and runtime-validated and include at minimum:
- stable
templateId; - immutable
version; - country;
- agency ID/name;
- output language;
- supported primary/secondary Case types;
- required and optional Case Facts;
- ordered section definitions;
- agency-specific drafting instructions;
- permitted/required standard wording;
- curated legal wording/references, if any;
- disclosure guidance/default review prompts;
- official submission guidance and destination metadata;
lastReviewedAt(operational/legal-content review date); if submission guidance is older than 180 days, show a non-blocking “verify current official guidance” warning and direct the user to the official source before submission.
A TypeScript/JSON registry validated with Valibot is appropriate; do not build a generic arbitrary JSON-schema authoring platform.
Version semantics
- Creating a report records the exact template ID/version.
- Updating a template means adding a new immutable version.
- Existing draft/finalized reports never silently migrate.
- A user may explicitly create a new report revision using a newer template version.
- Finalized snapshot records template version and a content/config fingerprint sufficient to reproduce/audit the selected definition.
Legal wording in v1
- No open-web legal research during generation.
- Any statutory/legal references must be vetted content included in the curated template/version.
- The drafting model may incorporate vetted wording only within template instructions and the grounded facts supplied.
- The model must not independently conclude that a crime/offense has been legally established.
9. Default AI: Cloudflare Workers AI
Cloudflare Workers AI is the zero-configuration default report generation/editing provider.
Privacy requirements
Current Cloudflare documentation states Workers AI inputs/outputs are Customer Content and are not used to train Workers AI models or improve Cloudflare/third-party services without explicit consent. Persistent content storage is not inherent to inference and should only occur where this product explicitly stores its own Case/report data.
Implementation requirements:
- Use a dedicated first-party inference Function/direct Workers AI binding, explicitly routed ahead of the generic archive proxy.
- Before spending app-funded inference, require the §13 deployment-trusted archive + current project-access boundary and enforce privacy-safe per-project/IP rate limits. If that validation fails, default Workers AI is unavailable rather than anonymous; local/manual and direct BYOM workflows remain available.
- The inference route is stateless: process Case Facts in memory, return
Cache-Control: no-store, and do not persist prompts/responses. Persist an accepted report only through the separate Case/report storage path after client validation/acceptance. - Never place report prompts/responses, Case Facts, generated reports, or sensitive transcript text in ordinary logs.
- If Cloudflare AI Gateway is used, payload logging must be disabled and AI response caching must be disabled for this traffic.
- Apply report-specific minimum disclosure before inference; re-review privacy behavior whenever provider/Gateway behavior changes.
10. Voice editing: Groq Whisper
Voice applies only to new user editing instructions, never to selected evidence audio.
Flow:
- capture microphone audio for one instruction;
- send it to the configured Groq Whisper transcription endpoint;
- receive transcript;
- discard the ephemeral recording from application working state once transcription completes/fails, except any short-lived browser buffer required to retry the current action;
- display transcript in the text instruction composer;
- user may edit/cancel it;
- only when the user submits the transcript does the selected report generation/editing model receive the instruction.
Groq request/key path and retention requirement
Voice transcription uses a dedicated first-party Pages Function (explicitly routed ahead of the generic archive proxy). It requires the same deployment-trusted archive + current project-access/rate-limit boundary as app-funded Workers AI. The app-owned Groq key stays in Cloudflare environment secrets and is never shipped to the browser. The Function forwards only the current ephemeral recording to Groq, does not persist request/response bodies, returns Cache-Control: no-store, and never logs audio/transcript content. If trusted-archive/current-project validation fails, app-funded voice transcription is unavailable. The transcript is returned to the browser for user review; accepted transcript text becomes report-editing input only after the user submits it.
Production voice editing is enabled only when the deployment has an explicit operator attestation such as GROQ_ZDR_ATTESTED=true, set after the operator has verified and documented that the Groq account/model used for transcription is covered by Zero Data Retention (ZDR). The deployment runbook records the verification date. The API response itself is not evidence of ZDR, so feature availability must fail closed when this attestation is absent.
Current Groq documentation says ordinary inference data may be temporarily logged for reliability/abuse for up to 30 days and that ZDR is available for audio transcription. Re-review this assumption when the provider/account/model changes.
11. Bring Your Own Model (BYOM)
Cloudflare remains the default. BYOM is an explicit advanced option for stronger or organization-controlled models.
Provider profiles
Settings → AI Providers supports:
- official OpenAI preset;
- official Anthropic preset;
- custom OpenAI-compatible endpoint;
- custom Anthropic-compatible endpoint.
A profile contains:
- local profile ID/display name;
- compatibility/provider type;
- base URL (fixed for official presets, configurable for custom);
- API key/token;
- configured model IDs;
- optional best-effort discovered models;
- default model(s);
- enabled/disabled state;
- last successful connection-test metadata (no secret/payload).
Always allow manual model ID entry because compatible endpoints do not implement every discovery API consistently.
Model selection
Users can configure independent device-local defaults for:
- Report generation
- Report editing
At each generate/rewrite action, users can override the model/provider for that operation.
Voice transcription remains the app-configured Groq Whisper path in v1.
One model runs per operation in v1. The abstraction must allow future separate drafting/legal-analysis/verification models, but do not implement ensemble consensus now.
For interoperability/privacy, v1 OpenAI-compatible calls use the stateless Chat Completions shape (/v1/chat/completions, store:false where accepted) and v1 Anthropic-compatible calls use the Messages shape (/v1/messages). Do not use provider conversations/files/background jobs or other server-persistent features for report drafting. Model discovery is best-effort; manual model IDs remain the source of truth when discovery is unavailable.
Credential storage and request path
- BYOM credentials are device-local only and must never sync to project storage, D1, R2, Cases, reports, activity history, telemetry, or AI provenance.
- Use local browser/device storage appropriate to sensitive app configuration (the exact IndexedDB/local persistence implementation may follow existing app conventions); do not interpret “local storage” as requiring the JavaScript
localStorageAPI. - Do not claim credentials are securely encrypted at rest unless there is a real user-held/OS-backed encryption secret. Obfuscation is not encryption.
- Hide stored secret values after save; allow replace/remove, not accidental reveal/copy in normal UI.
- Clearly warn that a browser-held API key can be accessed by code running in that origin and is weaker than server-held custody. Official OpenAI guidance says not to expose API keys in client-side code, and Anthropic’s SDK disables browser use by default for the same reason; BYOM is an intentional advanced, user-controlled exception. Recommend restricted/short-lived keys where supported.
For v1, custom/BYOM calls should be browser → configured provider endpoint directly, rather than a generic CoMapeo server relay. This preserves the user’s control of the key, avoids transmitting the key through CoMapeo infrastructure, supports organization/local endpoints, and avoids creating a generic server-side URL fetch/SSRF surface.
Consequences:
- provider endpoint must permit browser CORS for this origin;
- Test connection must detect/report CORS and compatibility failures;
- v1 custom endpoints must use HTTPS; plain-HTTP endpoints, including localhost/LAN HTTP endpoints, are unsupported in the production HTTPS app;
- the repository’s current CSP already permits outbound
https:connections (connect-src 'self' https: blob:), so custom HTTPS endpoints require no CSP weakening and no dynamic CSP mutation; - do not broaden CSP beyond the current
https:allowance for BYOM; - if a provider cannot be called safely from the browser, v1 must explain that it is unsupported rather than silently proxying the secret through CoMapeo.
Retention and training warnings
Provider warnings are shown when configuring the provider and before first use with Case data (and again after base URL/provider type changes). Store the acknowledgement locally. Provider documentation links and a Last reviewed date must be visible so these warnings can be maintained as policies change.
Official OpenAI preset
Show a warning materially equivalent to:
OpenAI data retention: OpenAI states that API inputs and outputs are not used to train its models by default unless the customer opts in. Standard abuse-monitoring logs may contain prompts/responses and are retained for up to 30 days by default, with exceptions for legal/security requirements. Eligible organizations can obtain modified/zero-data-retention controls, but CoMapeo cannot assume those controls are enabled for your account. Verify your OpenAI data-control settings before sending sensitive Case data.
Implementation must use a stateless/non-persistent API path for v1 where practicable (for example, avoid provider-side conversations/files/background storage features and explicitly disable storage where the API supports that control). Do not advertise “Zero Data Retention” unless the app can actually establish the user account/request is covered.
Policy last reviewed for this spec: 2026-08-17.
Official Anthropic preset
Show a warning materially equivalent to:
Anthropic data retention: Anthropic states that commercial API inputs and outputs are not used to train its models by default unless the customer opts in/otherwise provides permission. Standard API inputs/outputs are ordinarily deleted within 30 days, with exceptions including certain services/features, usage-policy enforcement, legal requirements, and account agreements. Zero Data Retention may be available by agreement and can have model-specific limitations. Verify your Anthropic workspace/model settings before sending sensitive Case data.
Do not advertise “Zero Data Retention” unless the app can establish the user account/model/request is covered.
Policy last reviewed for this spec: 2026-08-17.
Custom OpenAI-/Anthropic-compatible endpoint
Compatibility labels describe API shape, not privacy behavior. Show a stronger unknown-provider warning materially equivalent to:
Unknown data handling: This endpoint is configured by you. CoMapeo cannot verify who operates it or whether submitted data is retained, logged, used for training, transferred to other jurisdictions/services, or protected appropriately. OpenAI-compatible/Anthropic-compatible does not mean the endpoint follows OpenAI’s or Anthropic’s privacy terms. Do not send sensitive Case data unless you trust the endpoint and understand its policy.
Require explicit acknowledgement before first Case-data request after profile creation or base-URL change.
BYOM and disclosure
Using a custom provider never bypasses the Case disclosure gate. The same approved Case Facts payload is used regardless of model provider. Photos and evidence audio are never sent to BYOM models in v1.
12. Report branding
Branding is project-scoped in v1 because the app has no separate organization entity.
Do not reuse the existing project icon as the report organization logo: project identity and issuing-organization identity are semantically different.
Fields
- organization name — defaults to project name, editable independently;
- organization logo — optional.
UI
Provide Report branding on the Home/project experience, with a clear upload/edit/remove action. It may also be linked from the report creation/finalization UI when branding is missing or needs review.
Logo constraints
- PNG, JPEG, WebP;
- no SVG in v1;
- sensible validation such as max 2 MB input and max 2048×2048 decoded dimensions, with client-side downscale where appropriate;
- preserve transparency where the output pipeline supports it;
- no AI analysis of the logo.
No logo must still produce a clean text-only document header.
Finalized reports snapshot the exact organization name/logo artifact/version used; later branding edits never mutate old report output.
One issuing organization/logo per project in v1. Multi-party/co-signed reports are future scope.
13. Local-first storage, project sync, and authorization
Current app architecture has IndexedDB/Dexie local data and archive bearer-token authentication but no app user identity, membership, or role model. Do not invent per-user Case RBAC in this feature.
Local source of working state
Cases, report working drafts, local activity metadata, report branding cache, sync state and finalized snapshots/artifact metadata must be available from local IndexedDB/Dexie so the workspace remains usable offline.
Follow existing repository/data-layer patterns and schema-version/migration discipline rather than introducing a parallel state store.
Durable remote project storage
For remotely backed projects, add project-scoped durable storage for Cases/reports/artifacts. Recommended Cloudflare split:
- D1: structured Case/report/revision/template-selection/disclosure/activity metadata and synchronization revisions;
- R2: project report logo plus immutable finalized PDF, disclosure-safe media derivatives and manifests. Raw original evidence media is never copied into reporting R2 in v1; retain only its source reference/hash in report metadata.
This storage is a CoMapeo Cloud reporting workspace; it does not change the underlying CoMapeo archive record format.
Authorization boundary
Cloudflare-funded reporting services (D1/R2 storage, Workers AI and Groq) are available only for deployment-trusted archive bases. A deployment-controlled exact normalized-base allowlist/registry (not client/user configurable) prevents an attacker from standing up a fake archive to consume storage/inference. Untrusted/custom archives remain local-first and may use direct BYOM.
For every server-side reporting request:
- client supplies archive target context + its existing bearer token + remote project ID;
- normalize/validate the base using existing
normalizeArchiveBaseUrl()rules and require an exact match in the deployment trusted-archive registry; - make a minimal authenticated upstream
GET /projects/{projectId}with that bearer token; - only on success may D1/R2 or app-funded AI/voice work proceed; never persist/log the bearer token.
Namespace records with a server-secret HMAC of canonical archive base + project ID. Perform one upstream check per first-party reporting API request and batch work behind it; do not cache authorization across requests in v1. Any untrusted base, 401/403, timeout, 5xx or unreachable upstream fails closed for remote/app-funded operations while preserving local state.
This means v1 authorization is project access, not individual user identity.
Local/unreachable archives
If an archive is untrusted by the deployment registry, local/private, or unreachable from the edge, the Case remains fully local-first. The UI must show that remote Case sync and app-funded AI/voice are unavailable for that project; direct BYOM may still work.
Remote retention, access and deletion
- D1/R2 Case/report content has no automatic expiry in v1; while retained, finalized revisions are immutable, not undeletable.
- Delete Case is an explicit destructive action. Offline deletion creates a pending tombstone; once online and project access is revalidated, the server hard-deletes that Case’s D1 content and R2 artifacts. A content-free opaque deletion tombstone may be retained only as needed to stop an offline device resurrecting the Case.
- Deleting/updating an upstream observation does not silently erase an already-finalized evidentiary snapshot; the user must delete the Case to purge that retained snapshot.
- R2 buckets are private. Downloads go through an authenticated first-party Function after the same project-access check, with
Cache-Control: private, no-store; no anonymous bucket URLs or long-lived public links. - Do not promise Brazil-specific data residency unless the deployed D1/R2 configuration has been explicitly verified to provide it. Remote-sync UI/help must state that Case/report data is stored in the configured Cloudflare deployment and link the deployment privacy information.
- Application deletion removes live application objects; provider backup/legal retention, if any, is governed by the deployed provider/account terms and must not be described as instantaneous physical erasure.
Permissions
Any user who can access the project in the current Cloud App can, in v1:
- see/edit its remotely synchronized Cases;
- add/remove evidence;
- generate/edit reports;
- finalize reports.
Finalization does not claim organizational approval. It means only that the user deliberately froze this report version as ready to share.
A future real identity/membership system may introduce Viewer/Contributor/Approver roles and finalizedBy identity without changing the Case/report lifecycle.
Sync semantics
- Local edits mark the Case/report state dirty/pending sync.
- Synchronize when connected and project authorization succeeds.
- Use optimistic revision/version checks for mutable Case/draft records.
- If the server revision changed since the local base revision, return a conflict and require explicit reconciliation/reload/duplicate action.
- No silent last-write-wins.
- Do not implement CRDT/realtime collaborative editing in v1.
- Finalized revisions are append-only/immutable server records.
- Finalizing
(reportId, revisionNumber)is compare-and-set on a canonical finalized-snapshot hash: first distinct snapshot wins; the same snapshot hash is idempotent success; a different hash returns409 FINALIZATION_CONFLICT. PDF/media byte hashes are artifact integrity fields, not the CAS identity. - A losing offline device keeps its local artifact readable as Finalized locally — sync conflict. It must never overwrite or be silently renumbered; the user can discard it or explicitly Create as new revision, which uses the server/current Case lineage to allocate/validate the next revision number.
A locally finalized report may show Finalized — pending sync until remote artifacts and metadata are durably stored. Local finalization must not depend on network availability if all required evidence/artifacts are present locally.
14. Offline behavior
The repository already registers a VitePWA/Workbox service worker. New Case/report routes, bundled PDF fonts and required static assets must remain available through that app-shell precache. On first durable Case use, request navigator.storage.persist() and surface storage persistence/quota status. If persistence is denied, do not block work, but warn that browser eviction can remove unsynced local-only evidence/reports and recommend remote sync and/or explicit download.
Must work offline when required local data is available
- create/edit Case;
- add/remove already-local evidence;
- select/deselect local media;
- edit Case facts;
- inspect map/timeline using locally available map/data capabilities;
- manually edit existing report drafts;
- inspect finalized report snapshots;
- finalize a manual/previously generated report when every required selected evidence asset is locally available;
- render/download the PDF from a complete finalized local snapshot.
Requires connectivity
- Cloudflare AI generation/editing;
- BYOM calls to non-local endpoints;
- Groq Whisper voice transcription;
- remote Case/report synchronization;
- fetching missing remote evidence/media;
- opening official submission sites;
- platform sharing that itself depends on online recipient apps/services.
AI unavailability must never make existing Case/report content inaccessible or destructive.
15. Finalization and immutable snapshot
Finalization creates an immutable report revision containing enough data to reproduce and audit the report without silently reading newer mutable source values.
Snapshot at minimum:
- Case/report/revision IDs;
- report content/structured sections;
- selected evidence list + stable evidence numbering;
- normalized evidence data actually used;
- source record IDs and source version IDs where available;
- selected disclosure-transformed coordinates/geometries/location summaries;
- selected media source reference + original hash where available, plus the disclosure-safe derivative bytes/hash actually embedded/shared; raw original media remains in the underlying CoMapeo source and is not duplicated to reporting R2;
- user-authored photo captions;
- organization name + exact logo artifact/version;
- agency/template ID/version/fingerprint;
- AI operation provenance for accepted generated/rewrite operations;
- disclosure choices;
- unresolved non-blocking warnings acknowledged at finalization;
- finalized timestamp;
- local/remote sync status.
Do not invent a finalizedBy named person until the app has an authenticated user identity. The data model may reserve an optional future identity field.
Finalized content is append-only. Source record edits/deletion, template updates, model changes, branding changes, or Case changes never mutate the finalized revision.
16. PDF and evidence presentation
PDF technology
Use a deterministic client-side @react-pdf/renderer v4 document pipeline for v1, generated from the finalized snapshot rather than from arbitrary live DOM/HTML.
Requirements:
- A4 layout;
- bundled/local font(s) with reliable Portuguese/Unicode coverage — no runtime remote-font dependency;
- organization logo/name header;
- recipient agency/report title/case reference/date;
- agency-specific sections;
- requested action section where template uses it;
- disclosure-safe map when spatial evidence is included;
- evidence appendix;
- stable pagination/page numbers where practical;
- selected photos with user-authored captions and disclosure-safe metadata;
- selected audio listed as separate supporting evidence;
- pin PDF metadata (creation/modification date, title/author/producer/ID where controllable) from the finalized snapshot so re-rendering the same snapshot is deterministic;
- deterministic filename.
Example filename:
2026-08-17_IBAMA_Illegal-Mining_Case-Name_v1.pdf
Sanitize filename components for normal filesystems and ensure collisions do not overwrite local browser data silently.
Map
When report evidence contains permitted spatial information, include a report map derived only from disclosed locations/geometries.
- Exact: may render exact geometry.
- Area only: never render hidden exact points. Render only an independently existing user-approved generalized territory/boundary; absent one, that evidence contributes no map geometry.
- Omit: do not render the hidden location.
If nothing remains map-safe after these rules, omit the map section. Otherwise the map must be reproducible from the finalized snapshot. Do not make finalization depend on a network basemap tile request; use a clean vector-only/simple evidence map fallback from approved snapshot geometry when needed.
Evidence bundle
The shareable artifact contains the PDF plus metadata-scrubbed derivatives and a manifest binding evidence numbers, source references, original hashes and derivative hashes. Raw originals stay in the underlying CoMapeo source/local cache and are never copied into reporting R2 or the share bundle. If a safe derivative cannot be produced, block that file from the bundle.
The UI may offer PDF only and PDF + evidence files. Where native multi-file share is unsupported, provide a downloadable archive/bundle fallback.
17. Sharing and official submission
Share
- Share is always explicit and after finalization.
- Prefer browser/platform Web Share file flow when file sharing is supported.
- This can surface WhatsApp/email/other installed handlers without hard-coding third-party SDK submission.
- If file sharing is unsupported, provide download + clear manual-share guidance.
- Never send/share automatically after AI generation or finalization.
Official submission guidance
Each agency template includes maintained official-channel guidance.
- Show How to submit separately from Share.
- Clearly state that downloading/emailing/WhatsApp-sharing is not equivalent to official filing unless the agency explicitly says so.
- Opening a government submission URL does not let CoMapeo claim successful submission.
- v1 does not scrape/fill/submit Fala.BR, MPF, PF, or other government systems.
Agency submission guidance is operationally mutable; show/track template lastReviewedAt and update template versions when material requirements change.
18. Activity history
Record metadata-only meaningful events such as:
- Case created/status changed/reopened;
- evidence added/removed;
- media inclusion changed;
- report created/generated;
- AI revision accepted;
- disclosure changed;
- report finalized;
- new revision created;
- export/share action initiated when the app can reliably observe it;
- sync conflict/resolution.
Do not duplicate raw Case facts, prompt text, report content, transcript content, or media into the activity log.
Without a real user identity, do not fabricate actor names. Events may record device/session-safe technical provenance only if useful and privacy-safe.
19. Failure, retry, conflict, and idempotency behavior
AI generation/rewrite
- No partial draft mutation on failure.
- Timeouts/provider errors/schema-invalid output/unknown source refs show recoverable failure.
- Retry can reuse the same operation idempotency key or create an explicit new attempt without duplicate applied revisions.
- User can switch provider/model or continue manually.
Voice transcription
- Failure leaves the report unchanged.
- User can retry recording or type the instruction.
- Raw voice audio is not persisted beyond the active transcription attempt/retry buffer.
PDF/artifact generation
- Finalization validates that all blocking selected assets are available first.
- Rendering failure does not corrupt/finalize a half-built artifact; preserve the snapshot and permit deterministic retry.
- R2/upload failure after local finalization results in pending sync, not loss of the local finalized revision.
Sync
- Auth failure: preserve local state and surface reauthentication requirement.
- Unreachable remote archive: preserve local state and show project Case sync unavailable/pending.
- Version conflict: never auto-overwrite; show explicit resolution path.
- Retrying finalized sync is idempotent by report revision + canonical snapshot hash; artifact hashes verify uploaded bytes.
20. Privacy, security, and observability requirements
- Never send unselected project data to an AI provider.
- Never send photo/evidence-audio bytes to report LLMs in v1.
- Never log Case Facts, prompts, report bodies, selected evidence content, Groq audio, voice transcripts, BYOM API keys, or archive bearer tokens.
- Ordinary operational logs may record opaque IDs, provider/model ID, durations, token/usage/cost metrics where available, status/error codes, retry counts, and non-sensitive artifact sizes.
- Error reporting/Sentry must scrub request bodies, authorization headers, provider credentials, transcripts, and report/evidence payloads.
- Cloudflare AI Gateway payload logging/caching is forbidden for this traffic unless a future privacy review explicitly changes the requirement.
- BYOM direct requests must not be routed through a generic server-side URL fetcher.
- Keep the current CSP
connect-src 'self' https: blob:unchanged for BYOM; accept only custom HTTPS endpoints and test that plain HTTP custom endpoints are rejected. - Logo/media rendering must validate content type/size and avoid SVG/script-capable inputs in v1.
- Finalized artifact URLs must not become anonymous public URLs by default; access must remain project-authorized or be downloaded/shared explicitly by the user.
21. Accessibility, responsive UX, and i18n
- New UI copy must use existing
react-intlpatterns and ship en/pt/es translations with no raw-string regressions. - Brazil report/template output content is pt-BR in v1.
- Cases/Data multi-selection, disclosure controls, report editor, provider settings, branding upload, map/list/timeline, finalization dialogs and error states must be keyboard accessible and correctly labelled.
- Async screens/actions use project-standard skeleton/loading/error patterns.
- Design/QA at minimum desktop 1440×900 and mobile 375×812.
- Report editor and evidence/disclosure flows must be genuinely usable on mobile, not desktop dialogs squeezed into a narrow viewport; use full-screen/bottom-sheet patterns where appropriate to existing app conventions.
prefers-reduced-motionbehavior follows existing UI conventions.
22. Testing requirements for implementation
Implementation child issues/PRs follow AGENTS.md/TDD and the repository’s normal gates. The complete feature needs automated coverage for:
- Case lifecycle/project scoping, both evidence-entry paths, media selection, changed/deleted/unsynced states, and sync conflicts;
- disclosure transforms and fixed fixtures proving hidden coordinates plus photo EXIF/audio metadata do not appear in provider payloads, PDF/share derivatives, activity/log output;
- Case Facts/template versioning, AI schema/source-ref rejection, mandatory authorship/provenance transitions, transactional/idempotent application, and an adversarial grounding fixture set;
- Cloudflare stateless/no-log/no-cache behavior; Groq server key custody + ZDR-attestation fail-closed path; BYOM local-secret/no-sync/HTTPS+CORS/provider-warning/model-selection behavior;
- private authenticated R2 access, Delete Case D1/R2 purge/tombstone behavior, remote-auth fail-closed semantics, local PWA persistence/eviction-warning behavior;
- branding/finalized snapshots, metadata-scrubbed evidence bundles, PDF A4/Unicode/map fallback/AI-assistance footer/file naming, Web Share/download, and submission-guidance staleness;
- en/pt/es, accessibility, desktop 1440×900 and mobile 375×812 visual/E2E behavior.
Before completion run lint, typecheck, unit/coverage, React Doctor, Storybook/visual checks and relevant Playwright E2E, including offline/error/conflict/privacy scenarios.
23. Acceptance criteria
- Two entry paths work: Data/Alerts/Tracks → new/existing Case, and Cases → new Case → evidence browser; Cases are single-project, lightweight to create, support one primary + secondary types, and can represent an incident or pattern.
- Evidence supports observations, alerts, tracks and user context; parent-record selection and individual photo/audio selection are separate, and evidence media is never AI-interpreted in v1.
- Case workspace provides Overview, Evidence (list/timeline + map), Reports and metadata-only Activity; CSV/GeoJSON remain separate Exports.
- Brazil v1 has immutable/versioned FUNAI, IBAMA, MPF and PF templates with maintained official-submission guidance and a >180-day staleness warning.
- Each selected agency gets an independent report/evidence/disclosure/failure/finalization state.
- Disclosure is approved per report and supports identities, people, Exact/Area only/Omit location, individual media and other sensitive fields; hidden location cannot leak through AI payloads, maps, logs, activity or shared-media metadata.
- Shared photo/audio evidence uses metadata-scrubbed derivatives with original→derivative hashes; raw originals stay in the underlying CoMapeo source/local cache and never reporting R2.
- Before AI use, the user sees/approves the exact context categories being sent; newly disclosed sensitive context requires renewed approval.
- Case Facts are deterministic/minimal; AI results are Valibot-validated, reject unknown provenance IDs, preserve the old draft on failure, and maintain mandatory
ai|userblock authorship. Missing facts become review/blocking items rather than fabricated values. - Cloudflare Workers AI/Groq are available only to deployment-trusted, currently authorized remote projects; routes are stateless/no-store/rate-limited and AI Gateway payload logging/caching is disabled.
- Voice uses server-held Groq credentials only for new editing instructions, never evidence audio; transcript is user-reviewed and feature availability fails closed without operator-recorded ZDR attestation/date.
- BYOM supports official OpenAI/Anthropic and custom compatible HTTPS endpoints, device-local unsynced secrets, explicit CORS/HTTP failures, provider/model defaults + per-operation override, and the specified OpenAI/Anthropic/custom retention warnings without unverified ZDR claims.
- Report branding supports project-scoped organization name + optional PNG/JPEG/WebP logo from Home, separate from project icon, and snapshots exact branding on finalization.
- Local Case/manual report/PDF work is PWA-offline capable, requests persistent storage and warns on eviction risk; local/private projects remain usable even when remote/app-funded services cannot validate them.
- Remote storage is private D1/R2 for deployment-trusted projects; current archive access is revalidated without persisting bearer tokens. Divergent offline finalization returns a conflict (first snapshot wins; loser can create a new revision), and Delete Case purges live content/artifacts.
- Report lifecycle is Draft → immutable Finalized; edits create a new revision. Finalization snapshots report/evidence versions, media, disclosure, template, branding, AI provenance and artifacts; changed/deleted/unavailable evidence is never silently dropped.
- Client-side A4 PDF is reproducible from the snapshot with pt-BR/Unicode, branding, agency structure, AI-assistance footer, disclosure-safe map/evidence appendix and offline vector-map fallback.
- Share is explicit after Finalize, supports PDF/evidence bundle through native share or download fallback, and is clearly separate from official How to submit guidance/status.
- Logs/error reporting contain no Case Facts, report/prompt/media/transcript contents, provider secrets or archive bearer tokens.
- UI is en/pt/es localized, accessible, and verified at 1440×900 and 375×812.
24. Recommended implementation decomposition
Do not implement this entire specification as one giant PR. After this parent specification is accepted, create linked implementation issues with explicit dependencies and executable scopes. Recommended split:
- Cases foundation + local model/lifecycle/navigation — Case tables/repositories/hooks/routes, overview/activity skeleton, offline-first CRUD.
- Evidence selection + disclosure foundation — Data/Add-to-case, Alerts/Tracks entry, Case evidence browser, attachment selection, timeline/map, changed/deleted/unsynced handling, disclosure transforms.
- Project report branding — organization name/logo UI, validation, local/remote asset lifecycle, report snapshot contract.
- Brazil template registry + Case Facts contract — typed/versioned FUNAI/IBAMA/MPF/PF templates, Case Facts normalization/provenance, official submission metadata.
- Cloudflare AI generation/editor — server inference, structured validation, transactional revisions, Needs review, no-payload-logging/cache guardrails.
- Groq Whisper voice editing — ephemeral recording, ZDR guard, transcript review, editor integration.
- BYOM providers/models — local secrets/profiles, OpenAI/Anthropic/custom adapters, retention warnings, direct browser/CORS handling, per-task defaults/overrides.
- Remote Case/report sync + authorization — D1/R2 project namespace, archive access validation, optimistic conflict handling, immutable artifact sync/pending state.
- Finalization + PDF/evidence bundle + sharing — immutable snapshots,
@react-pdf/renderer, disclosure-safe/vector map, evidence archive, native share/download, official submission guidance UX. - Cross-feature hardening/QA — privacy logging guardrails, offline/conflict/failure E2E, accessibility/i18n/responsive/visual coverage and full regression gates.
Dependency details should be captured when child issues are created; parallel work is possible after the foundational Case/evidence contracts stabilize (for example branding, templates, and some provider adapter work can proceed independently).
25. Future phases explicitly enabled by this architecture
International/country packs
Add country → agency → report/case-type template packs without changing the Case core.
Richer permissions
Once CoMapeo Cloud has a real user identity/project-membership system, add Viewer/Contributor/Approver roles and trustworthy finalizedBy/approval identity.
Responsible evidence-media understanding
Future photo/audio interpretation/transcription may be added only with explicit language/community quality evaluation, disclosure controls, provenance, and human review. Indigenous-language evidence must not be treated as a trivial extension of mainstream-language Whisper transcription.
Highly controlled legal analysis
Future architecture may add a distinct legal-analysis stage capable of language such as “this may constitute offense X under article Y,” but only after a separate specification establishes:
- vetted/current jurisdiction-specific legal corpus;
- exact source citations and effective-date/version tracking;
- jurisdiction/competence checks;
- calibrated uncertainty and contradiction handling;
- evaluation against expert-reviewed cases;
- model/version provenance;
- independent verification where appropriate;
- explicit human approval before legal conclusions enter an official report.
Keep this as a distinct stage (Evidence → Case Facts → factual synthesis → routing → legal analysis → report drafting) rather than allowing the general drafting model to silently acquire legal-diagnosis authority.
26. Research inputs and maintenance note
This specification was reviewed against current official information on 2026-08-17. Provider and agency operational/privacy policies are mutable and must not be treated as immutable product facts.
Official sources reviewed include:
- Cloudflare Workers AI data usage/privacy documentation;
- Cloudflare AI Gateway logging/caching documentation;
- Groq data controls / Zero Data Retention documentation;
- OpenAI API data controls/data usage documentation;
- Anthropic Privacy Center/API retention and model-training documentation;
- FUNAI Ouvidoria guidance;
- IBAMA Linha Verde/Fala.BR environmental complaint guidance;
- Polícia Federal Comunica PF guidance;
- Ministério Público Federal representation/MPF Serviços guidance.
Implementation should link the relevant official provider/agency policy pages from warning/help UI and store a human-maintained lastReviewedAt for policy-sensitive template/provider guidance. Material policy changes should ship as reviewed template/UI updates; they must not retroactively mutate finalized reports.
Repository constraints confirmed during specification
- Current
mainhas no Cases/Reports route/domain/template/report storage. - Existing observations/alerts/tracks/attachments already provide the core evidence primitives.
- Current Data UI already has observation search/filter/map concepts that should be reused rather than duplicated.
- Existing CSV/GeoJSON observation export should remain separate.
- Current local persistence is Dexie/IndexedDB and should be extended through existing data-layer/repository patterns.
- Current authentication is archive bearer-token based; there is no user/role model, which is why v1 Case authorization inherits project access.
- Current
/api/*Pages Function architecture requires explicit routing for new first-party Case/report endpoints so they are not accidentally treated as generic archive-proxy traffic. - Current project has no PDF dependency; v1 intentionally selects a dedicated deterministic client-side PDF renderer rather than print-to-DOM behavior.
Definition of ready
This parent issue is implementation-ready as a product/architecture specification. Implementation should begin only through the linked/split executable child issues above, each following AGENTS.md and the repository’s full test/review workflow. No unresolved product decision from the original discovery checklist should be delegated to an implementation agent.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Cases and Case data model sections, then locate the existing Data selection/filter/map UI and the current project-scoped navigation. Trace how selected observations, alerts, and tracks are represented before deciding where the Cases workspace fits. Done means the Brazil v1 journeys, agency-specific drafts, disclosure review, immutable finalization, PDF/evidence bundle, and offline/online behavior are implemented without changing Exports.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai, full-stack, mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100