# Loom - Prototype Architecture Document

**Version:** 0.1  
**Status:** Initial prototype proposal  
**Platform:** Progressive Web App (PWA)  
**Initial local persistence:** ZangoDB on top of IndexedDB  
**Immediate goal:** deliver a functional, offline-first prototype usable on smartphone.

---

## 1. Product vision

**Loom** is a planner centered on projects, tasks, notes, time, and costs.

The goal is not to reproduce a paper planner in digital pages. Loom should behave like a personal organization system where each project is a thread, and tasks, notes, expenses, decisions, and time records form the fabric of work.

### Value proposition

Loom should quickly answer four questions:

1. What do I need to do today?
2. What is the next action for each project?
3. What is overdue or waiting on someone?
4. Where is the information I recorded?

### Product principle

> Do not just manage tasks. Weave progress.

---

## 2. Prototype objectives

The first prototype should allow users to:

- create and organize areas;
- create projects;
- create tasks and subtasks;
- define next action;
- register notes;
- plan tasks by date;
- register budget, expenses, income, and financial commitments;
- search information;
- operate offline;
- persist data locally;
- export and import data as JSON;
- work well on smartphone and desktop.

---

## 3. Out of initial scope

Do not implement in the first prototype:

- cross-device synchronization;
- authentication;
- multi-user collaboration;
- Google Calendar integration;
- binary attachments;
- remote push notifications;
- complete accounting;
- invoicing;
- tax document issuing;
- artificial intelligence features;
- server synchronization.

These capabilities may be added after the local model is validated.

---

## 4. Conceptual model

```text
Area
  └── Project
        ├── Tasks
        ├── Notes
        ├── Financial entries
        ├── Time entries
        └── History
```

### Main entities

- **Area**: broad life/work domain.
- **Project**: planning and tracking unit.
- **Task**: executable action.
- **Note**: textual information linked to a project or task.
- **FinancialEntry**: expense, income, or commitment.
- **TimeEntry**: time spent on a task/project.
- **Tag**: cross-cutting classification.
- **ActivityLog**: history of relevant events.

---

## 5. High-level architecture

```mermaid
flowchart TB
    User[User]

    subgraph PWA[Loom PWA]
        UI[Responsive UI]
        Router[Routing]
        App[Application services]
        Domain[Domain rules]
        Repository[Repositories]
        Search[Local search]
        Export[Import and export]
        SW[Service Worker]
        Cache[(Asset cache)]
        Zango[ZangoDB]
        IDB[(IndexedDB)]
    end

    User --> UI
    UI --> Router
    Router --> App
    App --> Domain
    App --> Repository
    App --> Search
    App --> Export
    Repository --> Zango
    Zango --> IDB
    SW --> Cache
    SW --> UI
```

---

## 6. Layered architecture

```mermaid
flowchart TB
    Presentation[Presentation Layer\nViews, components, forms, navigation]
    Application[Application Layer\nUse cases, orchestration, validation]
    Domain[Domain Layer\nProject, task, finance rules]
    Persistence[Persistence Layer\nRepositories and ZangoDB]
    Platform[Platform Layer\nIndexedDB, Service Worker, File APIs]

    Presentation --> Application
    Application --> Domain
    Application --> Persistence
    Persistence --> Platform
```

### Responsibilities

#### Presentation Layer

- screens;
- components;
- forms;
- navigation;
- visual states;
- responsiveness;
- user feedback.

#### Application Layer

- entity creation and updates;
- validation;
- summary calculations;
- repository orchestration;
- search;
- import/export.

#### Domain Layer

- status rules;
- progress calculation;
- financial calculations;
- next-action definition;
- overdue task rules;
- date consistency.

#### Persistence Layer

- ZangoDB access;
- index creation;
- queries;
- serialization;
- migrations;
- local backup.

---

## 7. Main navigation

For smartphone, use a bottom bar:

```mermaid
flowchart LR
    Today[Today] --- Projects[Projects] --- Add[Add] --- Calendar[Calendar] --- Search[Search]
```

### Secondary items

- Inbox;
- Areas;
- Weekly review;
- Finances;
- Time entries;
- Tags;
- Archived;
- Import;
- Export;
- Settings.

---

## 8. Main usage flow

```mermaid
flowchart TD
    Capture[Capture item] --> Inbox[Inbox] --> Clarify[Clarify]
    Clarify --> Project[Link to project]
    Clarify --> Task[Convert to task]
    Clarify --> Note[Convert to note]
    Task --> Schedule[Plan date] --> Execute[Execute] --> Complete[Complete] --> Review[Review] --> Project
```

---

## 9. Project states

```mermaid
stateDiagram-v2
    [*] --> planned
    planned --> active
    active --> waiting
    waiting --> active
    active --> paused
    paused --> active
    active --> completed
    completed --> archived
    planned --> archived
    paused --> archived
```

```javascript
const projectStatuses = [
    'planned',
    'active',
    'waiting',
    'paused',
    'completed',
    'archived'
];
```

---

## 10. Task states

```mermaid
stateDiagram-v2
    [*] --> inbox
    inbox --> planned
    planned --> inProgress
    inProgress --> waiting
    waiting --> inProgress
    planned --> cancelled
    inProgress --> completed
    completed --> archived
    cancelled --> archived
```

```javascript
const taskStatuses = [
    'inbox',
    'planned',
    'inProgress',
    'waiting',
    'completed',
    'cancelled',
    'archived'
];
```

---

## 11. Persistence with ZangoDB

```javascript
const db = new zango.Db('loomDatabase', {
    areas: ['name', 'archived'],
    projects: ['areaId', 'status', 'priority', 'dueDate', 'archived', 'updatedAt'],
    tasks: ['projectId', 'parentTaskId', 'status', 'priority', 'plannedDate', 'dueDate', 'completedAt', 'updatedAt'],
    notes: ['projectId', 'taskId', 'updatedAt'],
    tags: ['name', 'archived'],
    financialEntries: ['projectId', 'type', 'status', 'date', 'dueDate', 'categoryId'],
    financialCategories: ['name', 'type', 'archived'],
    timeEntries: ['projectId', 'taskId', 'startedAt', 'endedAt'],
    activityLogs: ['entityType', 'entityId', 'createdAt'],
    settings: ['key']
});
```

Use `crypto.randomUUID()` for all documents to support future synchronization.

---

## 12. Data diagram

```mermaid
erDiagram
    AREA ||--o{ PROJECT : contains
    PROJECT ||--o{ TASK : has
    TASK ||--o{ TASK : contains
    PROJECT ||--o{ NOTE : has
    TASK ||--o{ NOTE : references
    PROJECT ||--o{ FINANCIAL_ENTRY : records
    FINANCIAL_CATEGORY ||--o{ FINANCIAL_ENTRY : classifies
    PROJECT ||--o{ TIME_ENTRY : records
    TASK ||--o{ TIME_ENTRY : measures
    PROJECT }o--o{ TAG : tagged
    TASK }o--o{ TAG : tagged
    PROJECT ||--o{ ACTIVITY_LOG : generates
    TASK ||--o{ ACTIVITY_LOG : generates
```

---

## 13. Document conventions

```json
{
  "id": "uuid",
  "createdAt": "2026-07-15T22:00:00.000Z",
  "updatedAt": "2026-07-15T22:00:00.000Z",
  "archived": false,
  "schemaVersion": 1
}
```

### Dates

- store in ISO 8601;
- prefer UTC;
- convert to local timezone only in the UI.

### Money values

Store monetary values in cents to avoid floating-point errors:

```json
{
  "amount": 15990,
  "currency": "BRL"
}
```

---

## 14. Collection structures

Collections in the prototype:

- `areas`
- `projects`
- `tasks`
- `notes`
- `tags`
- `financialCategories`
- `financialEntries`
- `timeEntries`
- `activityLogs`
- `settings`

Document examples should follow the same schema shown in this document, with UUID ids and timestamp fields.

---

## 15. Full JSON export example

The complete export payload should include metadata and a `data` object with all collections, for example:

```json
{
  "application": "Loom",
  "exportVersion": 1,
  "exportedAt": "2026-07-15T22:30:00.000Z",
  "databaseSchemaVersion": 1,
  "data": {
    "areas": [],
    "projects": [],
    "tasks": [],
    "notes": [],
    "tags": [],
    "financialCategories": [],
    "financialEntries": [],
    "timeEntries": [],
    "activityLogs": [],
    "settings": []
  }
}
```

---

## 16. Suggested repositories

```text
src/
  data/
    database.js
    repositories/
      areaRepository.js
      projectRepository.js
      taskRepository.js
      noteRepository.js
      financeRepository.js
      timeRepository.js
      settingsRepository.js
```

Conceptual example:

```javascript
export class ProjectRepository {
    constructor(db) {
        this.collection = db.collection('projects');
    }

    async create(project) {
        const now = new Date().toISOString();
        const document = {
            id: crypto.randomUUID(),
            ...project,
            archived: false,
            createdAt: now,
            updatedAt: now,
            schemaVersion: 1
        };

        await this.collection.insert(document);
        return document;
    }

    async findById(id) {
        return this.collection.findOne({ id });
    }

    async findActive() {
        return this.collection
            .find({ archived: false, status: { $in: ['planned', 'active', 'waiting', 'paused'] } })
            .sort({ priority: -1, updatedAt: -1 })
            .toArray();
    }

    async update(id, changes) {
        const updatedAt = new Date().toISOString();
        await this.collection.update({ id }, { $set: { ...changes, updatedAt } });
        return this.findById(id);
    }
}
```

---

## 17. Suggested application services

```text
src/
  services/
    projectService.js
    taskService.js
    todayService.js
    searchService.js
    financeService.js
    timeService.js
    backupService.js
```

### todayService

Must aggregate:

- tasks planned for today;
- overdue tasks;
- in-progress tasks;
- priorities;
- upcoming financial commitments;
- active projects without next action.

### financeService

```javascript
const availableBudget = plannedBudget - paidExpenses - pendingCommitments;
const financialResult = receivedIncome - paidExpenses;
```

### projectService

Should compute:

- progress;
- next action;
- open task count;
- overdue task count;
- total hours;
- financial summary.

---

## 18. Local write flow

```mermaid
sequenceDiagram
    participant User
    participant UI
    participant Service
    participant Repo
    participant Zango
    participant IDB

    User->>UI: Create or update item
    UI->>Service: Send data
    Service->>Service: Validate and normalize
    Service->>Repo: Request persistence
    Repo->>Zango: insert/update
    Zango->>IDB: Write document
    IDB-->>Zango: Confirm
    Zango-->>Repo: Result
    Repo-->>Service: Saved document
    Service-->>UI: Update interface
```

---

## 19. Local search

The first version may use regular-expression search over textual fields.

Searchable fields:

- `projects.title`
- `projects.description`
- `tasks.title`
- `tasks.description`
- `notes.title`
- `notes.content`
- `financialEntries.description`
- `tags.name`

Escape user input before building regex expressions.

---

## 20. Import and export

### Export

- read all collections;
- assemble payload with metadata;
- generate JSON;
- offer download;
- do not export PWA caches.

### Import

- validate `application`;
- validate `exportVersion`;
- validate `databaseSchemaVersion`;
- support replace and merge modes;
- detect conflicts by `id`;
- create backup before replace.

---

## 21. Initial project structure

```text
loom/
  index.html
  manifest.webmanifest
  service-worker.js
  assets/
  css/
  src/
  docs/
  tests/
```

---

## 22. Minimum screens

### Today

- greeting;
- today tasks;
- overdue tasks;
- priorities;
- next action;
- quick capture button.

### Projects

- list;
- filters by area, status, priority;
- creation;
- search;
- simple indicators.

### Project detail

Tabs:

- Overview;
- Tasks;
- Notes;
- Costs;
- Time;
- History.

### Add

Modal/page with options:

- task;
- project;
- note;
- expense;
- income;
- commitment.

### Search

- search field;
- filters;
- grouped results by type.

---

## 23. Initial domain rules

1. Every active project must have a next action when open tasks exist.
2. A completed task must have `completedAt`.
3. A reopened task must remove `completedAt`.
4. Archived projects do not appear in main views.
5. Expenses and income must use integer cent values.
6. A subtask must belong to the same project as its parent task.
7. For the prototype, deletion should prefer archival.
8. Every relevant change must update `updatedAt`.
9. Automatic progress is computed from completed tasks.
10. The interface must keep working offline.

---

## 24. Prototype acceptance criteria

The prototype is considered functional when it is possible to:

- install the PWA;
- open the app without internet after first load;
- create an area;
- create a project;
- create tasks and subtasks;
- mark a task as completed;
- view today tasks;
- search project, task, and note;
- register an expense;
- view budget and balance;
- export all data;
- clear the database;
- import the exported JSON;
- recover all data correctly;
- use the app on smartphone screen size.

---

## 25. Implementation priority

### Stage 1 - Foundation

- HTML/CSS/JavaScript structure;
- PWA shell;
- manifest;
- service worker;
- ZangoDB database;
- repositories;
- demo data.

### Stage 2 - Core

- areas;
- projects;
- tasks;
- subtasks;
- Today view;
- forms.

### Stage 3 - Context

- notes;
- tags;
- search;
- filters.

### Stage 4 - Finance

- budget;
- expenses;
- income;
- commitments;
- financial summary.

### Stage 5 - Data safety

- export;
- import;
- database cleanup;
- backup before replacement.

---

## 26. Initial architectural decisions

### ADR-001 - Offline-first PWA

**Decision:** Loom will be usable without connectivity.

**Reason:** primary usage includes smartphone and quick capture, and data must not depend on constant internet.

### ADR-002 - ZangoDB in the prototype

**Decision:** use ZangoDB on top of IndexedDB.

**Reason:** familiarity with Mongo-like API and reduced learning time.

**Consequence:** database access must stay isolated in repositories to allow future replacement.

### ADR-003 - UUID

**Decision:** use client-generated UUIDs.

**Reason:** avoid collisions and prepare future device synchronization.

### ADR-004 - Values in cents

**Decision:** monetary values are integers.

**Reason:** avoid floating-point rounding issues.

### ADR-005 - JSON exchange format

**Decision:** backup and migration will use versioned JSON.

**Reason:** simplicity, transparency, and easy debugging.

---

## 27. Guidance for the implementation agent

The implementation agent should:

1. prioritize simple, functional code;
2. use modular JavaScript;
3. avoid frameworks in the first prototype unless clearly necessary;
4. isolate all ZangoDB access;
5. avoid coupling views directly to database code;
6. implement mobile-first layouts;
7. use UUIDs;
8. store dates as ISO 8601;
9. store monetary values in cents;
10. implement import/export from the beginning;
11. keep diagrams and models in this document updated;
12. avoid remote synchronization at this stage.

---

## 28. Next steps after prototype

After validating real usage:

- review the data model;
- evaluate migration to another IndexedDB layer if needed;
- implement synchronization;
- add authentication;
- integrate calendar;
- add notifications;
- include attachments;
- implement weekly review;
- add reports;
- evaluate multi-user version.

---

## 29. Executive summary

Loom starts as an offline-first PWA based on ZangoDB and IndexedDB. The prototype focuses on areas, projects, tasks, notes, costs, and search in a mobile-first interface.

The architecture should remain modular, with clear separation between UI, services, domain, and persistence. Repository abstraction keeps the path open for replacing ZangoDB in the future without rewriting the full app.

The first prototype is not meant to be a complete platform. Its goal is to validate a daily planning experience that is fast on smartphone, searchable, reliable, and able to preserve context across multiple projects.
