Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions tools/v1/team/email-ownership-tracker/docs/ARCHITECTURE_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Email Ownership Tracker Architecture Plan

## Folder Boundary

All code, tests, fixtures, and notes for this tool live under:

```text
tools/v1/team/email-ownership-tracker/
```

This V1 team tool must stay isolated until a future integration issue explicitly
connects it to the mail product. This architecture issue does not modify the app
shell, dashboard layout, routing, inbox architecture, mail rendering engine,
authentication, wallet core, Stellar core, database schema, notification system,
or shared design system.

## Module Map

The intended mini-product is split into folder-local layers:

| Layer | Planned path | Responsibility |
| ---------- | ------------- | ---------------------------------------------------------------------- |
| Public API | `index.ts` | Re-export stable tool contracts only. |
| Types | `types/` | Define ownership events, owners, teams, history windows, and UI state. |
| Services | `services/` | Own pure ownership-history operations and in-memory adapters. |
| Guards | `guards/` | Validate unsafe input before services, hooks, storage, or rendering. |
| Hooks | `hooks/` | Bridge services to React state without importing app stores. |
| Components | `components/` | Render the isolated tracker surface and accessibility states. |
| Fixtures | `fixtures/` | Provide deterministic local data for tests and review. |
| Tests | `tests/` | Verify contracts, data boundaries, and behavior without app wiring. |
| Docs | `docs/` | Explain ownership, integration constraints, and review checklists. |

## Data Flow

The tool should use a one-way ownership flow:

```text
mail event snapshot
-> guards validate ids, emails, tags, attachments, and timestamps
-> services normalize ownership events and derive current owners
-> hooks expose loading, empty, error, and ready states
-> components render local state without mutating mailbox data
```

The current architecture contract does not add persistence, app routes, mailbox
mutation, notification delivery, or live network calls. Future feature issues can
add those adapters only through folder-local boundaries and should document the
new trust assumptions before wiring them.

## Internal Contracts

Public API:

- expose stable type names, service factories, and guard helpers through
`index.ts` only after the related implementation issue lands.
- do not re-export fixtures, tests, or private helper functions.

Types:

- use plain serializable objects for ownership events and owner summaries.
- represent timestamps as UTC ISO strings.
- avoid importing main app types from `src/`.

Services:

- accept already-guarded inputs and return copied data.
- keep ownership derivation deterministic for the same event order.
- paginate or window histories before expensive derivation.
- do not call network APIs, wallet APIs, database clients, or notification
senders.

Guards:

- reject unsafe ids, malformed emails, unsupported actions, invalid timestamps,
oversized histories, unsafe tags, and malformed attachment metadata.
- remain pure and synchronous unless a future issue explicitly adds async
validation.

Hooks:

- own only local UI state and invoke folder-local services.
- expose explicit `idle`, `loading`, `ready`, `empty`, and `error` states.
- avoid importing app stores, route state, auth state, wallet state, or inbox
internals.

Components:

- render from hook state and props only.
- include accessible names, focus behavior, and status regions for async states.
- do not edit the shared design system or app shell.

Fixtures and tests:

- keep data synthetic and deterministic.
- cover malformed input, large histories, empty ownership states, and handoff
notes.
- use local Node or Vitest tests that can run without product integration.

## Contributor Change Spec

Future contributors may:

- add files under this tool folder to complete feature, UI, security, and test
issues.
- add folder-local fixtures, docs, tests, services, hooks, and components.
- update this plan when a future issue changes module ownership.

Future contributors may not:

- modify `src/`, app routes, dashboard shell, inbox architecture, auth, wallet,
Stellar, database schema, notification providers, or shared UI primitives from
this issue.
- introduce production data, secrets, paid services, live provider calls, or
mailbox mutations.
- make this tool depend on another isolated tool folder.

## Review Checklist

- All changed files stay under `tools/v1/team/email-ownership-tracker/`.
- Architecture docs define components, services, hooks, tests, fixtures, and docs.
- Data ownership and dependency limits are explicit.
- No app integration code is added.
- Tests can verify the architecture contract without running the main app.
57 changes: 57 additions & 0 deletions tools/v1/team/email-ownership-tracker/docs/DATA_BOUNDARIES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Email Ownership Tracker Data Boundaries

## Owned Data

The isolated tool owns only synthetic or caller-provided data structures:

- ownership event snapshots.
- current-owner summaries derived from those snapshots.
- local team member references used by the tracker UI.
- attachment metadata, not attachment file bodies.
- local UI state such as loading, empty, error, and ready views.
- deterministic fixtures used by folder-local tests.

The tool does not own mailbox records, account identities, auth sessions,
wallet accounts, Stellar transactions, database rows, notification jobs, or
provider credentials.

## Boundary Rules

Input enters the tool as plain objects. Guards should validate shape, size, and
unsafe characters before any service, hook, component, or future adapter uses the
data. Services should return copied summaries and should not expose internal
mutable collections.

The tool must not write to an inbox, change message assignment state in the main
mail product, send notifications, persist records, or call a provider from this
architecture issue. Future integration work must document the owner of each
adapter before connecting it.

## Dependency Rules

Allowed dependencies:

- JavaScript and TypeScript standard language features.
- React only inside future `components/` and `hooks/` files.
- Existing project test tools for folder-local tests.
- Existing shared UI primitives only when a future UI issue permits components.

Forbidden dependencies for this architecture issue:

- imports from `src/features/`, `src/routes/`, app stores, inbox internals, auth,
wallet, Stellar, database, or notification modules.
- imports from other isolated tool folders.
- new npm packages, paid APIs, cloud services, wallet signatures, or production
credentials.

## Future Adapter Handoff

A future integration issue should create an adapter checklist before touching
product data:

1. identify the source mailbox event and its owner.
2. run guard helpers before transforming the event.
3. limit history windows and team member lists.
4. return copied summaries to UI code.
5. keep writes behind a separately reviewed ownership-write issue.
6. document any new persistence or notification behavior in this folder first.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"tool": "Email Ownership Tracker",
"root": "tools/v1/team/email-ownership-tracker/",
"releaseTier": "V1",
"audience": "team",
"modules": [
{
"name": "public-api",
"path": "index.ts",
"owner": "tool boundary",
"responsibility": "Re-export stable contracts only.",
"allowedImports": ["types", "services", "guards"],
"forbiddenImports": ["src/routes", "src/features", "wallet", "stellar", "database"]
},
{
"name": "types",
"path": "types/",
"owner": "data model",
"responsibility": "Define serializable ownership event and summary shapes.",
"allowedImports": [],
"forbiddenImports": ["src/", "services/", "components/"]
},
{
"name": "services",
"path": "services/",
"owner": "ownership logic",
"responsibility": "Derive current owners from guarded history events.",
"allowedImports": ["types", "guards"],
"forbiddenImports": ["src/", "wallet", "stellar", "database", "notification"]
},
{
"name": "guards",
"path": "guards/",
"owner": "input boundary",
"responsibility": "Reject malformed or hostile ownership inputs.",
"allowedImports": [],
"forbiddenImports": ["src/", "network", "database", "wallet"]
},
{
"name": "hooks",
"path": "hooks/",
"owner": "ui state bridge",
"responsibility": "Expose local state transitions around folder-local services.",
"allowedImports": ["types", "services", "guards"],
"forbiddenImports": ["src/routes", "src/features", "app stores", "wallet"]
},
{
"name": "components",
"path": "components/",
"owner": "isolated UI",
"responsibility": "Render tracker states without app-shell integration.",
"allowedImports": ["types", "hooks", "services", "fixtures"],
"forbiddenImports": ["src/routes", "src/features", "mail rendering", "database"]
},
{
"name": "fixtures",
"path": "fixtures/",
"owner": "review data",
"responsibility": "Provide deterministic synthetic data.",
"allowedImports": [],
"forbiddenImports": ["production data", "network", "secrets"]
},
{
"name": "tests",
"path": "tests/",
"owner": "contract verification",
"responsibility": "Verify architecture, data, and behavior contracts locally.",
"allowedImports": ["types", "services", "guards", "fixtures", "docs"],
"forbiddenImports": ["src/routes", "wallet", "stellar", "database"]
},
{
"name": "docs",
"path": "docs/",
"owner": "handoff notes",
"responsibility": "Document architecture, data ownership, and integration limits.",
"allowedImports": [],
"forbiddenImports": ["production credentials", "external provider setup"]
}
],
"forbiddenChangeAreas": [
"src/",
"app shell",
"dashboard layout",
"navigation",
"routing",
"inbox architecture",
"mail rendering",
"authentication",
"wallet core",
"Stellar core",
"database schema",
"shared design system"
]
}
Loading