Add Milestones 1 & 2: full-stack POS foundation with admin UI

- Node/Express/TypeScript API under /api/v1 with JWT auth (login, refresh, logout, /me)
- Prisma schema: vendors, users, roles, products, categories, taxes, transactions
- SQLite for local dev; Postgres via docker-compose for production
- Full CRUD routes for vendors, users, categories, taxes, products with Zod validation and RBAC
- Paginated list endpoints scoped per vendor; refresh token rotation
- React/TypeScript admin SPA (Vite): login, protected routing, sidebar layout
- Pages: Dashboard, Catalog (tabbed Products/Categories/Taxes), Users, Vendor Settings
- Shared UI: Table, Modal, FormField, Btn, PageHeader components
- Multi-stage Dockerfile; docker-compose with Postgres healthcheck
- Seed script with demo vendor and owner account
- INSTRUCTIONS.md, ROADMAP.md, .claude/launch.json for dev server config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 23:18:04 -05:00
parent fb62439eab
commit d53c772dd6
4594 changed files with 1876068 additions and 0 deletions

78
server/node_modules/zod/v3/helpers/parseUtil.d.cts generated vendored Normal file
View File

@@ -0,0 +1,78 @@
import type { IssueData, ZodErrorMap, ZodIssue } from "../ZodError.cjs";
import type { ZodParsedType } from "./util.cjs";
export declare const makeIssue: (params: {
data: any;
path: (string | number)[];
errorMaps: ZodErrorMap[];
issueData: IssueData;
}) => ZodIssue;
export type ParseParams = {
path: (string | number)[];
errorMap: ZodErrorMap;
async: boolean;
};
export type ParsePathComponent = string | number;
export type ParsePath = ParsePathComponent[];
export declare const EMPTY_PATH: ParsePath;
export interface ParseContext {
readonly common: {
readonly issues: ZodIssue[];
readonly contextualErrorMap?: ZodErrorMap | undefined;
readonly async: boolean;
};
readonly path: ParsePath;
readonly schemaErrorMap?: ZodErrorMap | undefined;
readonly parent: ParseContext | null;
readonly data: any;
readonly parsedType: ZodParsedType;
}
export type ParseInput = {
data: any;
path: (string | number)[];
parent: ParseContext;
};
export declare function addIssueToContext(ctx: ParseContext, issueData: IssueData): void;
export type ObjectPair = {
key: SyncParseReturnType<any>;
value: SyncParseReturnType<any>;
};
export declare class ParseStatus {
value: "aborted" | "dirty" | "valid";
dirty(): void;
abort(): void;
static mergeArray(status: ParseStatus, results: SyncParseReturnType<any>[]): SyncParseReturnType;
static mergeObjectAsync(status: ParseStatus, pairs: {
key: ParseReturnType<any>;
value: ParseReturnType<any>;
}[]): Promise<SyncParseReturnType<any>>;
static mergeObjectSync(status: ParseStatus, pairs: {
key: SyncParseReturnType<any>;
value: SyncParseReturnType<any>;
alwaysSet?: boolean;
}[]): SyncParseReturnType;
}
export interface ParseResult {
status: "aborted" | "dirty" | "valid";
data: any;
}
export type INVALID = {
status: "aborted";
};
export declare const INVALID: INVALID;
export type DIRTY<T> = {
status: "dirty";
value: T;
};
export declare const DIRTY: <T>(value: T) => DIRTY<T>;
export type OK<T> = {
status: "valid";
value: T;
};
export declare const OK: <T>(value: T) => OK<T>;
export type SyncParseReturnType<T = any> = OK<T> | DIRTY<T> | INVALID;
export type AsyncParseReturnType<T> = Promise<SyncParseReturnType<T>>;
export type ParseReturnType<T> = SyncParseReturnType<T> | AsyncParseReturnType<T>;
export declare const isAborted: (x: ParseReturnType<any>) => x is INVALID;
export declare const isDirty: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
export declare const isValid: <T>(x: ParseReturnType<T>) => x is OK<T>;
export declare const isAsync: <T>(x: ParseReturnType<T>) => x is AsyncParseReturnType<T>;