Files
edgeever/docs/project-structure.md
T
2026-07-03 17:02:58 +08:00

107 lines
3.8 KiB
Markdown

# EdgeEver Project Structure
```text
edgeever/
├── apps/
│ ├── web/
│ │ ├── public/
│ │ │ ├── manifest.webmanifest
│ │ │ └── icons/
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── App.tsx
│ │ │ │ └── routes.tsx
│ │ │ ├── components/
│ │ │ │ ├── editor/
│ │ │ │ ├── layout/
│ │ │ │ ├── memo-list/
│ │ │ │ ├── notebook-tree/
│ │ │ │ └── ui/
│ │ │ ├── hooks/
│ │ │ ├── lib/
│ │ │ ├── styles/
│ │ │ └── main.tsx
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── api/
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── env.ts
│ │ │ ├── db/
│ │ │ ├── routes/
│ │ │ │ ├── memos.ts
│ │ │ │ ├── notebooks.ts
│ │ │ │ └── resources.ts
│ │ │ └── services/
│ │ │ ├── merge-memos.ts
│ │ │ └── resource-store.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── site/
│ ├── public/
│ ├── src/
│ │ ├── components/
│ │ ├── content/
│ │ ├── layouts/
│ │ ├── pages/
│ │ └── styles/
│ ├── astro.config.mjs
│ ├── package.json
│ └── tsconfig.json
├── packages/
│ └── shared/
│ ├── src/
│ │ ├── content.ts
│ │ ├── index.ts
│ │ ├── schemas.ts
│ │ └── types.ts
│ ├── package.json
│ └── tsconfig.json
├── migrations/
│ └── 0001_initial.sql
├── docs/
│ └── project-structure.md
├── tailwind.config.ts
├── wrangler.toml
├── bun.lock
└── package.json
```
## Deployment Shape
EdgeEver should deploy as one Cloudflare Worker:
- `/api/*` is routed to the Hono app first.
- Static files from `apps/web/dist` are served by Workers Assets.
- Unknown static routes fall back to `index.html` for SPA and PWA navigation.
- `env.DB` is the D1 binding.
- `env.RESOURCES` is the R2 bucket binding for images and attachments.
The official website in `apps/site` is an Astro static site. It is built and
deployed independently from the product Worker, typically to Cloudflare Pages.
## Frontend Boundaries
- `components/layout` owns the responsive three-pane shell.
- `components/notebook-tree` renders recursive notebooks from `parent_id`.
- `components/memo-list` owns checkbox selection and merge action surfaces.
- `components/editor` owns TipTap integration and Markdown serialization.
- `lib/api-client.ts` should be the only browser module that talks to `/api/*`.
## API Boundaries
- `routes/*` should stay thin: validate input, call services, return JSON.
- `services/merge-memos.ts` owns the D1 transaction that creates a merged memo, soft deletes source memos, and re-points resources.
- `services/resource-store.ts` owns R2 object keys and upload/download URL policy.
- `db/*` owns SQL snippets and row mapping.
## Data Model Notes
- Notebook nesting is unbounded through `notebooks.parent_id`.
- Every memo belongs to exactly one notebook through `memos.notebook_id`.
- Merge output is represented by a new memo with `source_memo_ids` and `merge_source_count`.
- Merge inputs are retained as soft-deleted rows with `merged_into_memo_id`.
- R2 objects are not moved during merge; `resources.memo_id` is updated to the new memo.