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/0002_tenant_identity_foundation.sqlSQL
-- Gastro OS Sprint A — A-011 through A-019
-- Tenant / Identity foundation
-- PostgreSQL 18
create extension if not exists pgcrypto;
create table if not exists organizations (
id uuid primary key default gen_random_uuid(),
name text not null,
slug text not null,
default_locale text not null default 'en-GB',
status text not null default 'active',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint organizations_slug_unique unique (slug),
constraint organizations_status_check check (status in ('active','suspended','archived'))
);
create table if not exists locations (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete restrict,
name text not null,
code text,
timezone text not null default 'Europe/Berlin',
default_locale text not null default 'de-DE',
business_day_cutoff time not null default '04:00',
status text not null default 'active',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint locations_org_name_unique unique (organization_id, name),
constraint locations_org_code_unique unique (organization_id, code),
constraint locations_status_check check (status in ('active','inactive','archived'))
);
create index if not exists idx_locations_org_status
on locations(organization_id, status);
create table if not exists user_accounts (
id uuid primary key default gen_random_uuid(),
external_auth_subject text,
email_normalized text,
display_name text,
preferred_locale text not null default 'en-GB',
status text not null default 'active',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint user_accounts_external_subject_unique unique (external_auth_subject),
constraint user_accounts_email_unique unique (email_normalized),
constraint user_accounts_status_check check (status in ('active','disabled','locked'))
);
create table if not exists employees (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete restrict,
user_account_id uuid references user_accounts(id) on delete set null,
employee_number text,
first_name text not null,
last_name text not null,
display_name text,
preferred_locale text,
status text not null default 'active',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint employees_org_employee_number_unique unique (organization_id, employee_number),
constraint employees_status_check check (status in ('active','inactive','on_leave','terminated'))
);
create index if not exists idx_employees_org_status
on employees(organization_id, status);
create table if not exists memberships (
id uuid primary key default gen_random_uuid(),
organization_id uuid not null references organizations(id) on delete restrict,
user_account_id uuid not null references user_accounts(id) on delete restrict,
employee_id uuid references employees(id) on delete set null,
status text not null default 'active',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint memberships_org_user_unique unique (organization_id, user_account_id),
constraint memberships_status_check check (status in ('invited','active','suspended','revoked'))
);
create index if not exists idx_memberships_user_status
on memberships(user_account_id, status);
create table if not exists roles (
id uuid primary key default gen_random_uuid(),
organization_id uuid references organizations(id) on delete cascade,
role_key text not null,
display_name text not null,
description text,
is_system boolean not null default false,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
version bigint not null default 1,
constraint roles_scope_key_unique unique (organization_id, role_key)
);
create table if not exists permissions (
permission_key text primary key,
description text not null,
created_at timestamptz not null default now()
);
create table if not exists role_permissions (
role_id uuid not null references roles(id) on delete cascade,
permission_key text not null references permissions(permission_key) on delete cascade,
created_at timestamptz not null default now(),
primary key (role_id, permission_key)
);
create table if not exists membership_roles (
membership_id uuid not null references memberships(id) on delete cascade,
role_id uuid not null references roles(id) on delete cascade,
location_id uuid references locations(id) on delete cascade,
created_at timestamptz not null default now(),
primary key (membership_id, role_id, location_id)
);
create index if not exists idx_membership_roles_membership
on membership_roles(membership_id);
create index if not exists idx_membership_roles_location
on membership_roles(location_id);
-- Cross-tenant integrity helpers:
-- a membership may only reference an employee from the same organization.
create or replace function enforce_membership_employee_same_org()
returns trigger
language plpgsql
as $$
declare
employee_org uuid;
begin
if new.employee_id is null then
return new;
end if;
select organization_id into employee_org
from employees
where id = new.employee_id;
if employee_org is null or employee_org <> new.organization_id then
raise exception 'membership employee must belong to same organization'
using errcode = '23514';
end if;
return new;
end;
$$;
drop trigger if exists trg_membership_employee_same_org on memberships;
create trigger trg_membership_employee_same_org
before insert or update of employee_id, organization_id
on memberships
for each row
execute function enforce_membership_employee_same_org();
-- Role assignment scope integrity.
create or replace function enforce_membership_role_scope()
returns trigger
language plpgsql
as $$
declare
membership_org uuid;
role_org uuid;
location_org uuid;
begin
select organization_id into membership_org
from memberships where id = new.membership_id;
select organization_id into role_org
from roles where id = new.role_id;
if membership_org is null then
raise exception 'membership does not exist'
using errcode = '23503';
end if;
if role_org is not null and role_org <> membership_org then
raise exception 'role belongs to another organization'
using errcode = '23514';
end if;
if new.location_id is not null then
select organization_id into location_org
from locations where id = new.location_id;
if location_org is null or location_org <> membership_org then
raise exception 'location belongs to another organization'
using errcode = '23514';
end if;
end if;
return new;
end;
$$;
drop trigger if exists trg_membership_role_scope on membership_roles;
create trigger trg_membership_role_scope
before insert or update
on membership_roles
for each row
execute function enforce_membership_role_scope();

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%