# amarathorng/cambodian-village-foods architecture

> Architecture diagram of the GitHub repository amarathorng/cambodian-village-foods, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/amarathorng/cambodian-village-foods
- Repository: https://github.com/amarathorng/cambodian-village-foods

## Overview

Cambodian Village Foods is a bilingual living archive for preserving Cambodian food traditions and community stories. Visitors browse and search published foods; contributors sign in, submit entries with photos, and track their submissions while reviewers approve or return pending entries. The map separates public browsing, contribution and account flows, personal submission management, and moderation. Supabase provides server-side authentication, entry data, and photo storage. Some page and route implementations were not sampled, so their behavior and connections are included only where documented or evidenced by the source index.

Main entry points: [`app/page.js`](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/page.js) (Archive home), [`app/api/entries/route.js`](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/entries/route.js) (Entry collection API), [`app/supabase.js`](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/supabase.js) (Supabase client), [`app/api/my-entries/route.js`](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/my-entries/route.js) (Owner submissions API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_archive["Public archive"]
  node_home["Archive home<br/>[page.js]"]
  node_food_search["Food search<br/>[FoodSearch.js]"]
  node_food_filters["Location filters<br/>[FoodFilters.js]"]
  node_food_grid["Food grid<br/>[FoodGrid.js]"]
  node_food_card["Food card<br/>[FoodCard.js]"]
  node_food_detail["Food detail<br/>[FoodDetail.js]"]
  node_food_article["Food article<br/>[FoodArticle.js]"]
  node_archive_content["Archive storytelling"]
end

subgraph group_accounts["Accounts"]
  node_auth_pages["Login and signup<br/>[login.page.js]"]
  node_auth_api["Authentication routes<br/>[route.js]"]
  node_signup_api["Signup route<br/>[route.js]"]
end

subgraph group_contribution["Contribution"]
  node_contribute_form["Contribution form<br/>[contribute-form.js]"]
  node_entry_fields["Entry fields<br/>[EntryFields.js]"]
  node_entry_validation["Entry validation<br/>[entryValidation.js]"]
  node_entries_api["Entry collection API<br/>[route.js]"]
  node_entry_mapper["Entry mapping<br/>[entry-mapper.js]"]
  node_edit_form["Edit submission<br/>[EditForm.js]"]
end

subgraph group_tracking["Submission tracking"]
  node_my_entries["My submissions<br/>[MyEntries.js]"]
  node_my_entries_api["Owner submissions API<br/>[route.js]"]
  node_my_entry_card["Submission card<br/>[MyEntryCard.js]"]
  node_status_badge["Status badge<br/>[StatusBadge.js]"]
end

subgraph group_review["Review workflow"]
  node_review_queue["Reviewer queue<br/>[ReviewQueue.js]"]
  node_review_card["Review card<br/>[ReviewCard.js]"]
  node_review_api["Review queue API<br/>[route.js]"]
  node_review_decision_api["Review decision API<br/>[route.js]"]
end

node_visitor(("Archive visitor"))
node_supabase_client["Supabase client<br/>[supabase.js]"]
node_entries_store[("Entries database")]
node_photo_storage[("Photo storage")]

node_visitor -->|"browses"| node_home
node_home -->|"fetches published entries"| node_entries_api
node_home -->|"renders"| node_food_search
node_home -->|"renders"| node_food_filters
node_home -->|"renders filtered entries"| node_food_grid
node_food_grid -->|"renders"| node_food_card
node_home -->|"renders"| node_archive_content
node_food_detail -->|"renders"| node_food_article
node_entries_api -->|"creates client"| node_supabase_client
node_entries_api -->|"reads and writes entries"| node_entries_store
node_entries_api -->|"uploads photos"| node_photo_storage
node_entries_api -->|"maps records"| node_entry_mapper
node_auth_pages -.->|"authenticates"| node_auth_api
node_auth_pages -.->|"registers"| node_signup_api
node_auth_api -->|"creates client"| node_supabase_client
node_signup_api -->|"creates client"| node_supabase_client
node_visitor -->|"submits a story"| node_contribute_form
node_contribute_form -->|"renders fields"| node_entry_fields
node_entry_fields -->|"validates fields"| node_entry_validation
node_contribute_form -.->|"submits entry"| node_entries_api
node_my_entries -.->|"loads submissions"| node_my_entries_api
node_my_entries_api -->|"creates client"| node_supabase_client
node_my_entries_api -->|"reads owned entries"| node_entries_store
node_my_entries_api -->|"maps records"| node_entry_mapper
node_my_entries -->|"renders submissions"| node_my_entry_card
node_my_entry_card -->|"shows status"| node_status_badge
node_edit_form -->|"renders fields"| node_entry_fields
node_review_queue -->|"loads pending entries"| node_review_api
node_review_queue -->|"sends decisions"| node_review_decision_api
node_review_queue -->|"renders entries"| node_review_card
node_review_card -->|"shows status"| node_status_badge
node_review_api -->|"creates client"| node_supabase_client
node_review_api -->|"reads pending entries"| node_entries_store
node_review_api -->|"maps records"| node_entry_mapper
node_review_decision_api -->|"creates client"| node_supabase_client
node_review_decision_api -.->|"updates review state"| node_entries_store

click node_home "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/page.js"
click node_food_search "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodSearch.js"
click node_food_filters "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodFilters.js"
click node_food_grid "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodGrid.js"
click node_food_card "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodCard.js"
click node_food_detail "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/FoodDetail.js"
click node_food_article "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/FoodArticle.js"
click node_archive_content "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/ArchiveIntroduction.js"
click node_auth_pages "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/login.page.js"
click node_auth_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/auth/login/route.js"
click node_signup_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/auth/signup/route.js"
click node_contribute_form "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/contribute-form.js"
click node_entry_fields "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/EntryFields.js"
click node_entry_validation "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/entryValidation.js"
click node_entries_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/entries/route.js"
click node_entry_mapper "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/entry-mapper.js"
click node_edit_form "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/edit/EditForm.js"
click node_my_entries "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/my-entries/MyEntries.js"
click node_my_entries_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/my-entries/route.js"
click node_my_entry_card "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/MyEntryCard.js"
click node_status_badge "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/StatusBadge.js"
click node_review_queue "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/review/ReviewQueue.js"
click node_review_card "https://github.com/amarathorng/cambodian-village-foods/blob/main/components/ReviewCard.js"
click node_review_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/review/route.js"
click node_review_decision_api "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/review/%5Bid%5D/route.js"
click node_supabase_client "https://github.com/amarathorng/cambodian-village-foods/blob/main/app/supabase.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_home,node_food_search,node_food_filters,node_food_grid,node_food_card,node_food_detail,node_food_article,node_archive_content,node_supabase_client toneBlue
class node_auth_pages,node_auth_api,node_signup_api,node_entries_store,node_photo_storage toneAmber
class node_contribute_form,node_entry_fields,node_entry_validation,node_entries_api,node_entry_mapper,node_edit_form toneMint
class node_my_entries,node_my_entries_api,node_my_entry_card,node_status_badge toneRose
class node_review_queue,node_review_card,node_review_api,node_review_decision_api,node_visitor toneIndigo
```

## Components

### Public archive

- [Archive home](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/page.js): `app/page.js`
- [Food search](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodSearch.js): `components/FoodSearch.js`
- [Location filters](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodFilters.js): `components/FoodFilters.js`
- [Food grid](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodGrid.js): `components/FoodGrid.js`
- [Food card](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/FoodCard.js): `components/FoodCard.js`
- [Food detail](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/FoodDetail.js): `app/food/[id]/FoodDetail.js`
- [Food article](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/FoodArticle.js): `app/food/[id]/FoodArticle.js`
- [Archive storytelling](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/ArchiveIntroduction.js): `components/ArchiveIntroduction.js`

### Accounts

- [Login and signup](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/login.page.js): `app/login.page.js`
- [Authentication routes](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/auth/login/route.js): `app/api/auth/login/route.js`
- [Signup route](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/auth/signup/route.js): `app/api/auth/signup/route.js`

### Contribution

- [Contribution form](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/contribute-form.js): `app/contribute-form.js`
- [Entry fields](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/EntryFields.js): `components/EntryFields.js`
- [Entry validation](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/entryValidation.js): `components/entryValidation.js`
- [Entry collection API](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/entries/route.js): `app/api/entries/route.js`
- [Entry mapping](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/entry-mapper.js): `app/entry-mapper.js`
- [Edit submission](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/food/%5Bid%5D/edit/EditForm.js): `app/food/[id]/edit/EditForm.js`

### Submission tracking

- [My submissions](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/my-entries/MyEntries.js): `app/my-entries/MyEntries.js`
- [Owner submissions API](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/my-entries/route.js): `app/api/my-entries/route.js`
- [Submission card](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/MyEntryCard.js): `components/MyEntryCard.js`
- [Status badge](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/StatusBadge.js): `components/StatusBadge.js`

### Review workflow

- [Reviewer queue](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/review/ReviewQueue.js): `app/review/ReviewQueue.js`
- [Review card](https://github.com/amarathorng/cambodian-village-foods/blob/main/components/ReviewCard.js): `components/ReviewCard.js`
- [Review queue API](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/review/route.js): `app/api/review/route.js`
- [Review decision API](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/api/review/%5Bid%5D/route.js): `app/api/review/[id]/route.js`

### Other components

- **Archive visitor**
- [Supabase client](https://github.com/amarathorng/cambodian-village-foods/blob/main/app/supabase.js): `app/supabase.js`
- **Entries database**
- **Photo storage**

## Connections

- Archive visitor → Archive home: browses
- Archive home → Entry collection API: fetches published entries (evidence: `app/page.js`)
- Archive home → Food search: renders (evidence: `app/page.js`)
- Archive home → Location filters: renders (evidence: `app/page.js`)
- Archive home → Food grid: renders filtered entries (evidence: `app/page.js`)
- Food grid → Food card: renders (evidence: `components/FoodGrid.js`)
- Archive home → Archive storytelling: renders (evidence: `app/page.js`)
- Food detail → Food article: renders (evidence: `app/food/[id]/FoodDetail.js`)
- Entry collection API → Supabase client: creates client (evidence: `app/api/entries/route.js`)
- Entry collection API → Entries database: reads and writes entries (evidence: `app/api/entries/route.js`)
- Entry collection API → Photo storage: uploads photos (evidence: `app/api/entries/route.js`)
- Entry collection API → Entry mapping: maps records (evidence: `app/api/entries/route.js`)
- Login and signup → Authentication routes: authenticates
- Login and signup → Signup route: registers
- Authentication routes → Supabase client: creates client (evidence: `app/api/auth/login/route.js`)
- Signup route → Supabase client: creates client (evidence: `app/api/auth/signup/route.js`)
- Archive visitor → Contribution form: submits a story
- Contribution form → Entry fields: renders fields (evidence: `app/contribute-form.js`)
- Entry fields → Entry validation: validates fields (evidence: `components/EntryFields.js`)
- Contribution form → Entry collection API: submits entry
- My submissions → Owner submissions API: loads submissions
- Owner submissions API → Supabase client: creates client (evidence: `app/api/my-entries/route.js`)
- Owner submissions API → Entries database: reads owned entries (evidence: `app/api/my-entries/route.js`)
- Owner submissions API → Entry mapping: maps records (evidence: `app/api/my-entries/route.js`)
- My submissions → Submission card: renders submissions (evidence: `app/my-entries/MyEntries.js`)
- Submission card → Status badge: shows status (evidence: `components/MyEntryCard.js`)
- Edit submission → Entry fields: renders fields (evidence: `app/food/[id]/edit/EditForm.js`)
- Reviewer queue → Review queue API: loads pending entries (evidence: `app/review/ReviewQueue.js`)
- Reviewer queue → Review decision API: sends decisions (evidence: `app/review/ReviewQueue.js`)
- Reviewer queue → Review card: renders entries (evidence: `app/review/ReviewQueue.js`)
- Review card → Status badge: shows status (evidence: `components/ReviewCard.js`)
- Review queue API → Supabase client: creates client (evidence: `app/api/review/route.js`)
- Review queue API → Entries database: reads pending entries (evidence: `app/api/review/route.js`)
- Review queue API → Entry mapping: maps records (evidence: `app/api/review/route.js`)
- Review decision API → Supabase client: creates client (evidence: `app/api/review/[id]/route.js`)
- Review decision API → Entries database: updates review state
