glanzlicht / GastroOS
Verified secure showcase
500 Files 1 MB Public size 31 Redacted TypeScript · SQL · JSON · Markdown · DOCKERIGNORE · EXAMPLE

Project overview

GastroOS is a verified code showcase with 500 visible project entries across 3 top-level modules. The primary detected language is TypeScript; protected files remain visible in the structure while their contents stay private.

README

GastravaOS

GastravaOS is a modular Hospitality Operational Intelligence Platform.

The technical repository name remains GastroOS for compatibility. The product is presented publicly as GastravaOS.

Product preview

GastravaOS operations dashboard

GastravaOS is designed for hospitality operations ranging from small venues to larger multi-location organizations. The platform combines operational workflows, resilient data handling and role-specific user experiences without exposing internal complexity to operators.

What this repository demonstrates

This repository is presented as a technical portfolio showcase, not as a complete product blueprint.

It demonstrates work across:

  • backend engineering with Node.js, TypeScript, NestJS and REST/OpenAPI;
  • PostgreSQL data modeling, explicit SQL migrations and transactional consistency;
  • Flutter application architecture with Riverpod, go_router, Drift/SQLite and Dio;
  • operational workflows across hospitality domains;
  • offline-capable client foundations and synchronization patterns;
  • real-time state reconciliation and event-driven integration patterns;
  • integrations for storage, payments, fiscal/accounting systems and external platforms;
  • Docker-based development, CI, observability and runtime verification;
  • tenant-aware security, audit-oriented design and permission boundaries;
  • applied AI around deterministic domain data and human-controlled actions.

Technology stack

AreaTechnology
BackendNode.js 24 LTS, TypeScript, NestJS 11
APIREST / OpenAPI
DatabasePostgreSQL 18, Drizzle ORM, explicit SQL migrations
FrontendFlutter, Riverpod, go_router
Local dataDrift / SQLite
NetworkingDio, json_serializable
InfrastructureDocker Compose, S3-compatible storage
ArchitectureModular monolith, transactional outbox
QualityAutomated tests, CI, observability and runtime verification

Engineering approach

The codebase is organized around clear boundaries and reusable platform capabilities rather than one large feature layer.

Recurring engineering principles include:

  • deterministic and auditable domain state;
  • separation of operational truth from presentation;
  • role- and context-specific interfaces;
  • resilience under intermittent connectivity;
  • explicit integration adapters;
  • composable capabilities instead of duplicated vertical implementations;
  • controlled exposure of sensitive business, security and product logic.

Portfolio boundary

The public showcase intentionally omits detailed roadmaps, ADRs, security internals, commercial logic, AI prompts, operational playbooks and reconstructable product strategy.

Those materials remain in the private repository. The public view is optimized so technical reviewers can evaluate engineering breadth and implementation quality without receiving a reconstruction guide for the product.

Local development

The repository uses a versioned pnpm dependency graph.

corepack enable
pnpm install --frozen-lockfile

Project-specific runtime and verification details remain in the private engineering documentation.

Status

GastravaOS is under active development. The repository contains a broad implementation foundation and ongoing product work rather than a finished commercial release.

The public showcase focuses on engineering capability, architecture quality and implementation breadth while deliberately omitting core IP.

apps/backend/src/infrastructure/database/migrations/0032_sprint_p_files_import_export_notifications.sqlSQL
-- Sprint P — secure files, imports/exports and notifications.
create table if not exists file_assets (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
location_id uuid references locations(id) on delete set null,
owner_entity_type text,
owner_entity_id uuid,
purpose text not null,
storage_key text not null,
original_file_name text not null,
mime_type text not null,
size_bytes bigint not null,
checksum_sha256 text,
status text not null default 'uploading',
created_by_user_id uuid references user_accounts(id) on delete set null,
rejection_reason text,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
archived_at timestamptz,
deleted_at timestamptz,
constraint file_asset_status_check check(
status in ('uploading','processing','available','rejected','archived','deleted')
),
constraint file_asset_purpose_check check(
purpose in (
'recipe_media','training_media','task_evidence','incident_evidence',
'safety_evidence','employee_document','supplier_document','invoice_document',
'import_source','export_result','other'
)
),
constraint file_asset_size_positive check(size_bytes >= 0)
);
create unique index if not exists idx_file_assets_storage_key
on file_assets(storage_key);
create index if not exists idx_file_assets_owner
on file_assets(organization_id,owner_entity_type,owner_entity_id);
create table if not exists file_upload_sessions (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
location_id uuid references locations(id) on delete set null,
file_asset_id uuid not null references file_assets(id) on delete cascade,
expected_size_bytes bigint not null,
expected_mime_type text not null,
expected_checksum_sha256 text,
expires_at timestamptz not null,
completed_at timestamptz,
created_at timestamptz not null default now()
);
create index if not exists idx_file_upload_sessions_expiry
on file_upload_sessions(expires_at);
create table if not exists import_jobs (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
location_id uuid references locations(id) on delete set null,
import_type text not null,
file_asset_id uuid not null references file_assets(id) on delete restrict,
status text not null default 'uploaded',
mapping_json jsonb not null default '{}'::jsonb,
options_json jsonb not null default '{}'::jsonb,
created_by_user_id uuid references user_accounts(id) on delete set null,
created_at timestamptz not null default now(),
started_at timestamptz,
completed_at timestamptz,
summary_json jsonb,
version bigint not null default 1,
constraint import_status_check check(
status in ('uploaded','validating','preview_ready','importing','completed','failed','cancelled')
),
constraint import_type_check check(
import_type in (
'products','ingredients','recipes_basic','employees','guests','suppliers',
'supplier_products','inventory_opening_balance'
)
)
);
create index if not exists idx_import_jobs_org_status
on import_jobs(organization_id,status,created_at desc);
create table if not exists import_row_errors (
id uuid primary key default gen_random_uuid(),
import_job_id uuid not null references import_jobs(id) on delete cascade,
row_number integer not null,
field_name text,
error_code text not null,
message text not null,
raw_value_preview text,
severity text not null default 'error',
created_at timestamptz not null default now(),
constraint import_error_severity_check check(severity in ('warning','error'))
);
create index if not exists idx_import_row_errors_job_row
on import_row_errors(import_job_id,row_number);
create table if not exists import_preview_rows (
id uuid primary key default gen_random_uuid(),
import_job_id uuid not null references import_jobs(id) on delete cascade,
row_number integer not null,
normalized_json jsonb not null,
valid boolean not null,
deterministic_row_key text not null,
created_at timestamptz not null default now(),
constraint import_preview_row_unique unique(import_job_id,row_number),
constraint import_preview_key_unique unique(import_job_id,deterministic_row_key)
);
create table if not exists import_applied_rows (
id uuid primary key default gen_random_uuid(),
import_job_id uuid not null references import_jobs(id) on delete cascade,
deterministic_row_key text not null,
target_entity_type text not null,
target_entity_id uuid,
applied_at timestamptz not null default now(),
constraint import_applied_row_unique unique(import_job_id,deterministic_row_key)
);
create table if not exists export_jobs (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
location_id uuid references locations(id) on delete set null,
export_type text not null,
format text not null,
filters_json jsonb not null default '{}'::jsonb,
status text not null default 'queued',
requested_by_user_id uuid references user_accounts(id) on delete set null,
file_asset_id uuid references file_assets(id) on delete set null,
created_at timestamptz not null default now(),
started_at timestamptz,
completed_at timestamptz,
expires_at timestamptz,
error text,
constraint export_status_check check(
status in ('queued','processing','completed','failed','expired','cancelled')
),
constraint export_format_check check(format in ('csv','xlsx','pdf')),
constraint export_type_check check(
export_type in ('sales_report','inventory','waste','purchasing','employees','guests','safety','incidents','audit')
)
);
create index if not exists idx_export_jobs_org_status
on export_jobs(organization_id,status,created_at desc);
create table if not exists notifications (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
user_id uuid not null references user_accounts(id) on delete cascade,
location_id uuid references locations(id) on delete set null,
notification_type text not null,
title_key text not null,
body_key text not null,
params_json jsonb not null default '{}'::jsonb,
severity text not null default 'info',
related_entity_type text,
related_entity_id uuid,
status text not null default 'unread',
deduplication_key text,
created_at timestamptz not null default now(),
read_at timestamptz,
archived_at timestamptz,
constraint notification_status_check check(status in ('unread','read','archived')),
constraint notification_severity_check check(severity in ('info','attention','urgent','critical'))
);
create unique index if not exists idx_notifications_dedup
on notifications(organization_id,user_id,deduplication_key)
where deduplication_key is not null;
create index if not exists idx_notifications_user_status
on notifications(user_id,status,created_at desc);
create table if not exists notification_preferences (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete cascade,
user_id uuid not null references user_accounts(id) on delete cascade,
notification_type text not null,
in_app_enabled boolean not null default true,
email_enabled boolean not null default false,
push_enabled boolean not null default false,
quiet_hours_policy jsonb,
updated_at timestamptz not null default now(),
constraint notification_preference_unique unique(organization_id,user_id,notification_type)
);
create table if not exists notification_deliveries (
id uuid primary key default gen_random_uuid(),
notification_id uuid not null references notifications(id) on delete cascade,
channel text not null,
status text not null default 'queued',
provider text,
provider_message_id text,
attempt_count integer not null default 0,
next_attempt_at timestamptz,
last_attempt_at timestamptz,
last_error text,
created_at timestamptz not null default now(),
constraint notification_delivery_channel_check check(channel in ('in_app','email','push')),
constraint notification_delivery_status_check check(
status in ('queued','sending','sent','failed','dead_letter')
),
constraint notification_delivery_unique unique(notification_id,channel)
);
create index if not exists idx_notification_deliveries_queue
on notification_deliveries(status,next_attempt_at,created_at);
insert into permissions(permission_key,description) values
('files.read','Read authorized files'),
('files.upload','Upload files'),
('files.manage','Archive/manage files'),
('imports.read','Read import jobs'),
('imports.create','Create import jobs'),
('imports.execute','Confirm/execute import jobs'),
('exports.create','Create export jobs'),
('exports.read','Read/download export jobs'),
('exports.sensitive','Create sensitive exports')
on conflict(permission_key) do nothing;

Architecture

High-level modules detected from the verified public snapshot. Protected implementation details are intentionally omitted.

appsmodule
.vscodemodule
.githubmodule

Technology stack

TypeScriptSQLMarkdownJSONGITIGNOREDOCKERIGNORENode.js / JavaScript ecosystem
TypeScript68.8%
SQL20.0%
Markdown10.9%
JSON0.3%
GITIGNORE0.1%
DOCKERIGNORE0.0%
CJS0.0%
MJS0.0%