20260610220652
This commit is contained in:
1 parent
6cb198203d
commit
d7658b69e2
2 files changed
+395
-89
No files matched your search
+391
-89
@@ -1,129 +1,431 @@
|
|||||||
# Project Context
|
# Allapp Project Context
|
||||||
|
|
||||||
|
This file is a compact project memory for future Codex chats. Read it first when working in
|
||||||
|
`D:\workspace\code\app`.
|
||||||
|
|
||||||
## Workspace
|
## Workspace
|
||||||
|
|
||||||
- Root: `D:\workspace\code\app`
|
- Root: `D:\workspace\code\app`
|
||||||
- Git repository root: `D:\workspace`
|
- Git repository root: `D:\workspace`
|
||||||
- Projects:
|
- Backend: `app-go`
|
||||||
- `app-go`: Go backend.
|
- Frontend: `app-rn`
|
||||||
- `app-rn`: Expo / React Native frontend.
|
- Local database memo: `db.local.yml`
|
||||||
- Database connection memo:
|
- Treat config files as sensitive. Some local config files may contain real credentials.
|
||||||
- `D:\workspace\code\app\db.local.yml`
|
|
||||||
- This file is intentionally placed under `app` root and is currently Git-trackable.
|
## Product Mental Model
|
||||||
|
|
||||||
|
Allapp is shaped more like a mini-program platform than a single linear mobile app.
|
||||||
|
|
||||||
|
There is a main shell for the family/personal space, and feature modules behave like small apps
|
||||||
|
inside it. The frontend owns most product flow and business behavior. The backend is deliberately
|
||||||
|
thin and generic, acting mostly as auth, file storage, ID generation, and database access.
|
||||||
|
|
||||||
|
High-level model:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Allapp main shell
|
||||||
|
├── Home / Chat / Tools / My
|
||||||
|
├── Auth and family/space management
|
||||||
|
└── Sub-apps
|
||||||
|
├── Finance
|
||||||
|
│ ├── Home
|
||||||
|
│ ├── Add record
|
||||||
|
│ └── Analysis
|
||||||
|
└── Clothes matching
|
||||||
|
└── Planned/listed, route not implemented yet
|
||||||
|
```
|
||||||
|
|
||||||
|
Important naming note:
|
||||||
|
|
||||||
|
- The product often uses "family" and "space" as the same concept.
|
||||||
|
- Database tables use `b_family` and `b_family_member`.
|
||||||
|
- Main tab config currently includes `/space`, but there is no matching page yet.
|
||||||
|
|
||||||
## Backend: app-go
|
## Backend: app-go
|
||||||
|
|
||||||
- Tech stack: Go, Fiber v3, pgx PostgreSQL client, JWT, Viper, Zap, S3/RustFS, QQ/WeChat login.
|
Tech stack:
|
||||||
- Main entry: `app-go/cmd/app/main.go`
|
|
||||||
|
- Go
|
||||||
|
- Fiber v3
|
||||||
|
- pgx PostgreSQL client
|
||||||
|
- JWT
|
||||||
|
- Viper config
|
||||||
|
- Zap logging
|
||||||
|
- S3/RustFS file storage
|
||||||
|
- QQ/WeChat login and binding
|
||||||
|
- Snowflake-style unique ID generator
|
||||||
|
|
||||||
|
Important files:
|
||||||
|
|
||||||
|
- Entry: `app-go/cmd/app/main.go`
|
||||||
- Bootstrap: `app-go/internal/bootstrap/app.go`
|
- Bootstrap: `app-go/internal/bootstrap/app.go`
|
||||||
|
- Server: `app-go/internal/bootstrap/server.go`
|
||||||
- Routes: `app-go/internal/router/router.go`
|
- Routes: `app-go/internal/router/router.go`
|
||||||
- API base path from config: `/app`
|
- Config type: `app-go/internal/config/config.go`
|
||||||
|
- Request binding/validation: `app-go/internal/httpx/request.go`
|
||||||
|
- Response shape: `app-go/internal/httpx/response.go`
|
||||||
|
- Auth middleware: `app-go/internal/middleware/auth.go`
|
||||||
|
- Generic DB access: `app-go/pkg/db/*`
|
||||||
|
|
||||||
|
Bootstrap flow:
|
||||||
|
|
||||||
|
```text
|
||||||
|
config -> logger -> S3 client -> Postgres pool -> db.Init
|
||||||
|
-> unique ID -> JWT -> WeChat client -> Fiber server
|
||||||
|
```
|
||||||
|
|
||||||
|
API base path comes from config and is currently:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/app
|
||||||
|
```
|
||||||
|
|
||||||
Important endpoints:
|
Important endpoints:
|
||||||
|
|
||||||
- `POST /app/auth/login/qq`
|
```text
|
||||||
- `POST /app/auth/login/wechat`
|
POST /app/auth/login/qq
|
||||||
- `POST /app/bind/qq`
|
POST /app/auth/login/wechat
|
||||||
- `POST /app/bind/wechat`
|
POST /app/bind/qq
|
||||||
- `POST /app/data/loadData`
|
POST /app/bind/wechat
|
||||||
- `POST /app/data/loadDataBySql`
|
|
||||||
- `POST /app/data/saveData`
|
|
||||||
- `POST /app/data/getUniqueId`
|
|
||||||
- `POST /app/s3/upload`
|
|
||||||
- `POST /app/s3/delete`
|
|
||||||
|
|
||||||
Architecture notes:
|
POST /app/data/loadData
|
||||||
|
POST /app/data/loadDataBySql
|
||||||
|
POST /app/data/saveData
|
||||||
|
POST /app/data/getUniqueId
|
||||||
|
|
||||||
- Backend exposes generic data APIs that accept table/view names, conditions, raw SQL, and save payloads.
|
POST /app/s3/upload
|
||||||
- This matches the frontend's generic `loadDataApi`, `loadDataBySqlApi`, and `saveDataApi`.
|
POST /app/s3/delete
|
||||||
- There are no explicit database foreign keys; relationships are enforced by code and naming conventions.
|
```
|
||||||
- `go test ./...` currently fails in `pkg/uniqueid/IdGeneratorException.go` because `fmt.Println(message)` should likely be `fmt.Println(message...)`.
|
|
||||||
|
|
||||||
Security notes:
|
Backend architecture notes:
|
||||||
|
|
||||||
- Existing config files include live credentials.
|
- `loadData` accepts a table/view name, selected columns, condition string, order string, and args.
|
||||||
- User explicitly said they do not plan to modify the backend.
|
- `loadDataBySql` accepts raw SQL and args.
|
||||||
- Database access was allowed with full permissions via the connection in `db.local.yml`.
|
- `saveData` accepts batches of inserts, updates, and deletes by table name/key field.
|
||||||
|
- Insert/update helpers add audit fields for most tables via `applyMetaFields`.
|
||||||
|
- `Token` header is parsed by `middleware.Auth()` and stores `user_id` in context.
|
||||||
|
- There are no explicit database foreign keys in the inspected schema; relationships are enforced by code and naming conventions.
|
||||||
|
|
||||||
|
Security/architecture caution:
|
||||||
|
|
||||||
|
- The generic data API is very flexible but risky.
|
||||||
|
- Table names, columns, conditions, ordering, and raw SQL can come from the frontend.
|
||||||
|
- If this moves toward production, prioritize server-side table/field whitelists, ownership checks, and removing or restricting raw SQL.
|
||||||
|
|
||||||
|
Validation notes:
|
||||||
|
|
||||||
|
- `BindAndValidate` validates structs with `go-playground/validator`.
|
||||||
|
- It skips validation for slices.
|
||||||
|
- `GetUniqueIdReq.Count` currently uses a `binding` tag, not a `validate` tag, so its min/max rules may not run.
|
||||||
|
|
||||||
## Frontend: app-rn
|
## Frontend: app-rn
|
||||||
|
|
||||||
- Tech stack: Expo 55, React Native 0.83, React 19, expo-router, Zustand, Alova/Axios, HeroUI Native, Uniwind.
|
Tech stack:
|
||||||
- Main package file: `app-rn/package.json`
|
|
||||||
|
- Expo 55
|
||||||
|
- React Native 0.83
|
||||||
|
- React 19
|
||||||
|
- Expo Router
|
||||||
|
- Zustand
|
||||||
|
- Alova with Axios adapter
|
||||||
|
- HeroUI Native
|
||||||
|
- Uniwind / Tailwind-style classes
|
||||||
|
- Lucide React Native icons
|
||||||
|
- QQ/WeChat native login plugins
|
||||||
|
|
||||||
|
Important files:
|
||||||
|
|
||||||
|
- Package: `app-rn/package.json`
|
||||||
|
- App config: `app-rn/app.json`
|
||||||
- Root layout: `app-rn/src/app/_layout.tsx`
|
- Root layout: `app-rn/src/app/_layout.tsx`
|
||||||
- API wrapper: `app-rn/src/request/index.ts`
|
- Startup redirect page: `app-rn/src/app/index.tsx`
|
||||||
|
- Request wrapper: `app-rn/src/request/index.ts`
|
||||||
- API methods: `app-rn/src/request/api.ts`
|
- API methods: `app-rn/src/request/api.ts`
|
||||||
- User store: `app-rn/src/store/user.ts`
|
- User store: `app-rn/src/store/user.ts`
|
||||||
- Family store: `app-rn/src/store/family.ts`
|
- Family store: `app-rn/src/store/family.ts`
|
||||||
- Finance store: `app-rn/src/store/finance.ts`
|
- Finance store: `app-rn/src/store/finance.ts`
|
||||||
|
- Main shell layout: `app-rn/src/layouts/AppLayout.tsx`
|
||||||
|
- Module shell layout: `app-rn/src/layouts/ModuleLayout.tsx`
|
||||||
|
- Shared tabbar: `app-rn/src/components/layout/tabbar.tsx`
|
||||||
|
- App/module list config: `app-rn/src/configs/pages.ts`
|
||||||
|
|
||||||
Frontend/backend contract:
|
Frontend/backend contract:
|
||||||
|
|
||||||
- Frontend reads `EXPO_PUBLIC_API_URL`.
|
- Frontend reads `EXPO_PUBLIC_API_URL`.
|
||||||
- Requests use Alova with Axios adapter.
|
- Requests use Alova with Axios adapter.
|
||||||
- Auth token is sent in custom `Token` header.
|
- Auth token is sent in a custom `Token` header.
|
||||||
- Backend response shape is `{ code, message, data, track_id }`.
|
- Login APIs are whitelisted in the request wrapper.
|
||||||
- Success code is `1000`.
|
- Backend response shape:
|
||||||
- Unauthorized code is `1001`.
|
|
||||||
- Business error code is `2000`.
|
|
||||||
- System error code is `3000`.
|
|
||||||
|
|
||||||
Known frontend type-check issues:
|
```ts
|
||||||
|
{
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
data: unknown;
|
||||||
|
track_id?: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
- `pnpm exec tsc --noEmit` fails.
|
Response codes:
|
||||||
- `tsconfig.json` includes `**/*.ts` and `**/*.tsx`, which pulls in `example`.
|
|
||||||
|
```text
|
||||||
|
1000 success
|
||||||
|
1001 unauthorized/token expired
|
||||||
|
2000 business error
|
||||||
|
3000 system error
|
||||||
|
```
|
||||||
|
|
||||||
|
State:
|
||||||
|
|
||||||
|
- `user-storage`: persisted user token/id/nickname/avatar.
|
||||||
|
- `family-storage`: persisted current family id.
|
||||||
|
- Finance categories are in memory only and loaded by the finance module layout.
|
||||||
|
|
||||||
|
Startup flow:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/ index
|
||||||
|
├── no local token -> /auth/login
|
||||||
|
├── token exists but user check fails -> /auth/login
|
||||||
|
├── token exists but no family -> /family/entry
|
||||||
|
└── token exists and family exists -> /(tabs)/home
|
||||||
|
```
|
||||||
|
|
||||||
|
## Frontend Route Structure
|
||||||
|
|
||||||
|
Expo Router tree:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/app
|
||||||
|
├── _layout.tsx
|
||||||
|
├── index.tsx
|
||||||
|
├── +not-found.tsx
|
||||||
|
├── auth
|
||||||
|
│ └── login.tsx
|
||||||
|
├── (tabs)
|
||||||
|
│ ├── _layout.tsx
|
||||||
|
│ ├── home/index.tsx
|
||||||
|
│ ├── chat/index.tsx
|
||||||
|
│ ├── my/index.tsx
|
||||||
|
│ └── star/index.tsx
|
||||||
|
├── tools
|
||||||
|
│ └── index.tsx
|
||||||
|
├── family
|
||||||
|
│ ├── entry.tsx
|
||||||
|
│ ├── settings.tsx
|
||||||
|
│ ├── user.tsx
|
||||||
|
│ └── member/[id].tsx
|
||||||
|
└── finance
|
||||||
|
├── (tabs)
|
||||||
|
│ ├── _layout.tsx
|
||||||
|
│ ├── home/index.tsx
|
||||||
|
│ └── analysis/index.tsx
|
||||||
|
├── add/index.tsx
|
||||||
|
└── sub/index.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
Effective routes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/ startup redirect
|
||||||
|
/auth/login login
|
||||||
|
/home main home
|
||||||
|
/chat chat/image picker demo
|
||||||
|
/my profile tab
|
||||||
|
/star placeholder page, not currently in tab config
|
||||||
|
/tools app/module list
|
||||||
|
/family/entry create or join family
|
||||||
|
/family/settings family settings
|
||||||
|
/family/user user profile settings
|
||||||
|
/family/member/:id family member detail
|
||||||
|
/finance/home finance module home
|
||||||
|
/finance/add add finance record
|
||||||
|
/finance/analysis finance analysis
|
||||||
|
/finance/sub test page
|
||||||
|
```
|
||||||
|
|
||||||
|
Main tab config in `src/app/(tabs)/_layout.tsx`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/home 首页
|
||||||
|
/space 空间, but route currently missing
|
||||||
|
/tools center app-list button
|
||||||
|
/chat 聊天
|
||||||
|
/my 我的
|
||||||
|
```
|
||||||
|
|
||||||
|
Finance module tab config in `src/app/finance/(tabs)/_layout.tsx`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/finance/home 记账
|
||||||
|
/finance/add center add button
|
||||||
|
/finance/analysis 分析
|
||||||
|
```
|
||||||
|
|
||||||
|
Layout behavior:
|
||||||
|
|
||||||
|
- Root `_layout.tsx` renders a global Stack with no headers.
|
||||||
|
- `(tabs)/_layout.tsx` uses `AppLayout`, which renders `Slot`, top `Navbar`, and bottom `Tabbar`.
|
||||||
|
- `finance/(tabs)/_layout.tsx` uses `ModuleLayout`, a module-level shell with its own top bar and tabbar.
|
||||||
|
- `ModuleLayout` close action returns to `/(tabs)/home`.
|
||||||
|
|
||||||
|
Current route mismatches:
|
||||||
|
|
||||||
|
- Main tab points to `/space`, but no `/space` file exists.
|
||||||
|
- `src/app/(tabs)/star/index.tsx` exists but is not in the tab config.
|
||||||
|
- `/tools` is outside `(tabs)`, so it is not wrapped by `AppLayout`; decide whether this is intentional.
|
||||||
|
- `/finance/add` is outside `finance/(tabs)`, but the finance tabbar points to it. This can be intentional for a modal/subpage style add screen.
|
||||||
|
|
||||||
|
## Feature Status
|
||||||
|
|
||||||
|
Implemented or mostly implemented:
|
||||||
|
|
||||||
|
- QQ login
|
||||||
|
- WeChat login
|
||||||
|
- Auth persistence
|
||||||
|
- Auth-expired redirect
|
||||||
|
- Family creation
|
||||||
|
- Family joining by invite code
|
||||||
|
- Family settings
|
||||||
|
- User profile
|
||||||
|
- Avatar upload to S3/RustFS
|
||||||
|
- QQ/WeChat account binding
|
||||||
|
- App/module list page
|
||||||
|
|
||||||
|
Partially implemented:
|
||||||
|
|
||||||
|
- Finance module shell
|
||||||
|
- Finance category loading
|
||||||
|
- Finance add-record form UI
|
||||||
|
- Finance analysis placeholder/demo page
|
||||||
|
|
||||||
|
Not yet complete:
|
||||||
|
|
||||||
|
- Saving a finance record from `/finance/add`
|
||||||
|
- Finance record list on `/finance/home`
|
||||||
|
- Finance analysis real data
|
||||||
|
- Clothes matching app route
|
||||||
|
- `/space` main-tab page
|
||||||
|
|
||||||
|
## Database: allapp
|
||||||
|
|
||||||
|
Observed database:
|
||||||
|
|
||||||
|
- PostgreSQL version observed previously: 18.1
|
||||||
|
- Database: `allapp`
|
||||||
|
- Schema: `public`
|
||||||
|
- Explicit foreign keys: none observed
|
||||||
|
|
||||||
|
Tables:
|
||||||
|
|
||||||
|
```text
|
||||||
|
b_user
|
||||||
|
b_user_oauth
|
||||||
|
b_family
|
||||||
|
b_family_member
|
||||||
|
b_finance
|
||||||
|
b_finance_category
|
||||||
|
b_finance_category_default
|
||||||
|
```
|
||||||
|
|
||||||
|
Views:
|
||||||
|
|
||||||
|
```text
|
||||||
|
v_family_member
|
||||||
|
```
|
||||||
|
|
||||||
|
Main entities:
|
||||||
|
|
||||||
|
- `b_user`: user profile, nickname, avatar, last login time, name, phone, birth date.
|
||||||
|
- `b_user_oauth`: third-party login bindings; includes `user_id`, `type`, `openid`.
|
||||||
|
- `b_family`: family/space; includes `name`, `invite_code`, `owner_id`.
|
||||||
|
- `b_family_member`: family membership; includes `family_id`, `user_id`, `role`, `nickname`.
|
||||||
|
- `b_finance`: finance records; includes `category_id`, `family_id`, `amount`, `remark`, `record_time`.
|
||||||
|
- `b_finance_category_default`: default finance category template.
|
||||||
|
- `b_finance_category`: actual finance categories for a family.
|
||||||
|
- `v_family_member`: joins `b_family_member` with `b_user`.
|
||||||
|
|
||||||
|
Finance conventions:
|
||||||
|
|
||||||
|
```text
|
||||||
|
type = 0 expense
|
||||||
|
type = 1 income
|
||||||
|
```
|
||||||
|
|
||||||
|
Category icon names match frontend iconfont names, for example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
finance_jiaotong
|
||||||
|
finance_canyin
|
||||||
|
finance_shicai
|
||||||
|
finance_gouwu
|
||||||
|
finance_gongzi
|
||||||
|
finance_jianzhi
|
||||||
|
finance_shouru
|
||||||
|
```
|
||||||
|
|
||||||
|
## Local Environment Notes
|
||||||
|
|
||||||
|
The Codex shell runs inside WSL2 Ubuntu.
|
||||||
|
|
||||||
|
WSL has `fnm` installed at:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/home/oneao/.local/share/fnm/fnm
|
||||||
|
```
|
||||||
|
|
||||||
|
Known WSL Node setup:
|
||||||
|
|
||||||
|
```text
|
||||||
|
fnm 1.39.0
|
||||||
|
v22.22.3
|
||||||
|
v24.16.0 default
|
||||||
|
```
|
||||||
|
|
||||||
|
In non-interactive Codex commands, `~/.bashrc` may not initialize fnm automatically. If `node` is not
|
||||||
|
found, temporarily enable it with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PATH="$HOME/.local/share/fnm:$PATH"
|
||||||
|
eval "$(fnm env --shell bash)"
|
||||||
|
```
|
||||||
|
|
||||||
|
After fnm init, expected tools:
|
||||||
|
|
||||||
|
```text
|
||||||
|
node v24.16.0
|
||||||
|
pnpm 11.5.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows-side `nvm` paths may appear in PATH:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/mnt/d/devtool/nvm
|
||||||
|
/mnt/d/devtool/nodejs
|
||||||
|
```
|
||||||
|
|
||||||
|
Those are not the right runtime for WSL. Prefer WSL `fnm`.
|
||||||
|
|
||||||
|
## Known Type/Build Issues
|
||||||
|
|
||||||
|
Frontend:
|
||||||
|
|
||||||
|
- `pnpm exec tsc --noEmit` currently fails.
|
||||||
|
- `tsconfig.json` includes `**/*.ts` and `**/*.tsx`, pulling in `example`.
|
||||||
- `tsconfig.json` has a suspicious extra include entry: `src/app/auth/login_2`.
|
- `tsconfig.json` has a suspicious extra include entry: `src/app/auth/login_2`.
|
||||||
- Generated iconfont components have `react-native-svg` prop type incompatibilities.
|
- Generated iconfont components have `react-native-svg` prop type incompatibilities.
|
||||||
- `src/app/finance/(tabs)/analysis/index.tsx` has `Surface variant="2"` type mismatch.
|
- `src/app/finance/(tabs)/analysis/index.tsx` has `Surface variant="2"` type mismatch.
|
||||||
|
|
||||||
## Database: allapp
|
Backend:
|
||||||
|
|
||||||
- PostgreSQL version observed: 18.1.
|
- `go` was not available in the earlier command environment, so `go test ./...` could not be rerun there.
|
||||||
- Database: `allapp`.
|
- Prior context noted a possible unique ID package compile issue around `fmt.Println(message)` vs `fmt.Println(message...)`.
|
||||||
- User used for inspection: `postgres`.
|
|
||||||
- Schema: `public`.
|
|
||||||
- Tables: 7.
|
|
||||||
- Views: 1.
|
|
||||||
- Explicit foreign keys: none.
|
|
||||||
|
|
||||||
Tables and row counts at inspection time:
|
## Important Current Risks
|
||||||
|
|
||||||
- `b_user`: 1 row.
|
- Generic backend data APIs need server-side permissions before production use.
|
||||||
- `b_user_oauth`: 2 rows.
|
- Finance category loading currently queries all `b_finance_category` rows without filtering by current `family_id`.
|
||||||
- `b_family`: 1 row.
|
- Frontend business logic often trusts local/user-provided family and user IDs.
|
||||||
- `b_family_member`: 1 row.
|
- Main tab route `/space` is missing.
|
||||||
- `b_finance`: 0 rows.
|
- Some pages are placeholders or demos.
|
||||||
- `b_finance_category`: 20 rows.
|
|
||||||
- `b_finance_category_default`: 20 rows.
|
|
||||||
|
|
||||||
Main entities:
|
|
||||||
|
|
||||||
- `b_user`: user profile, including nickname, avatar, last login time, name, phone, birth date.
|
|
||||||
- `b_user_oauth`: third-party login bindings. Fields include `user_id`, `type`, `openid`.
|
|
||||||
- `b_family`: family/space. Fields include `name`, `invite_code`, `owner_id`.
|
|
||||||
- `b_family_member`: family membership. Fields include `family_id`, `user_id`, `role`, `nickname`.
|
|
||||||
- `b_finance`: finance records. Fields include `category_id`, `family_id`, `amount`, `remark`, `record_time`.
|
|
||||||
- `b_finance_category_default`: default finance category template.
|
|
||||||
- `b_finance_category`: actual finance categories for a family.
|
|
||||||
- `v_family_member`: view joining `b_family_member` with `b_user`.
|
|
||||||
|
|
||||||
View definition summary:
|
|
||||||
|
|
||||||
- `v_family_member` selects member fields from `b_family_member` and user profile fields from `b_user`.
|
|
||||||
- Join condition: `b_user.id = b_family_member.user_id`.
|
|
||||||
|
|
||||||
Finance category convention:
|
|
||||||
|
|
||||||
- `type = 0`: expense.
|
|
||||||
- `type = 1`: income.
|
|
||||||
- Category icons match frontend iconfont names, for example:
|
|
||||||
- `finance_jiaotong`
|
|
||||||
- `finance_canyin`
|
|
||||||
- `finance_shicai`
|
|
||||||
- `finance_gouwu`
|
|
||||||
- `finance_gongzi`
|
|
||||||
- `finance_jianzhi`
|
|
||||||
- `finance_shouru`
|
|
||||||
|
|
||||||
## Useful Mental Model
|
|
||||||
|
|
||||||
This is a small full-stack personal/family app. The backend is intentionally generic and thin, while most product behavior lives in the React Native frontend and database table conventions. The database is part of the project context and should be considered when understanding features.
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
allowBuilds:
|
||||||
|
'@parcel/watcher': true
|
||||||
|
core-js: true
|
||||||
|
core-js-pure: true
|
||||||
Reference in new issue
Block a user