ViewTouch Point of Sale
GNU/Linux Restaurant Point of Sale software - Free and open source POS solution
RepeatlyOS is a city marketplace for local Lebanese businesses and the operating system they run on — orders, bookings, payments, and customers, all in one place.
CommerceTypeScript · PLpgSQLGitHub @Georges51379OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
RepeatlyOS is a city marketplace where shoppers find real local businesses —
and the operating system those businesses run on: orders, bookings,
payments, and customers, all in one place. Launched in Batroun and Shekka,
Lebanon.
This repo holds two things at different stages of maturity, and it's worth
knowing which is which before you dig in:Read the full README ↗RepeatlyOS is a city marketplace where shoppers find real local businesses — and the operating system those businesses run on: orders, bookings, payments, and customers, all in one place. Launched in Batroun and Shekka, Lebanon.
This repo holds two things at different stages of maturity, and it's worth knowing which is which before you dig in:
/, /:citySlug, /app, /onboarding,
/platform-admin). This is what's described below./dashboard/*, kept around from before the Supabase build-out. It runs
entirely on fake in-memory data (src/context/DemoContext.tsx) and has no
connection to the real backend. Useful for showing off UI polish quickly
with zero setup, not representative of what a real business actually sees.For shoppers: browse a city's page (/batroun, /shekka), search across
every business in it — including a rule-based natural-language search
(/discover, try "nike basketball shoes in shekka") that falls back to
neighboring cities in the same region if nothing matches, or a real GPS-radius
"near me" search — add items from multiple businesses to one cart, and check
out as a guest (no account needed). Verified photo reviews, a verified-business
badge, live power-cut-aware "closed right now" status, and a city-wide loyalty
wallet (earn at any participating business, redeem at any other) round out the
shopping side.
For business owners: sign up, get approved, and run the shop from
/app/:businessId/* — products, inventory (a real append-only movement
ledger, not just a number you edit), orders, bookings with staff assignment
and overlap-safe scheduling, customers, tasks, payments, and analytics
(revenue heatmap, 30-day forecast, churn-risk flags, a health score, referral
leaderboard) — all computed from real data via Postgres functions, not
estimated client-side.
For the platform: a super-admin dashboard to approve businesses, open new cities, assign SaaS plans, manage the USD/LBP exchange rate shown throughout the marketplace, and revoke passkeys.
npm install
cp .env.example .env # fill in your Supabase project URL + anon key
npm run dev # → http://localhost:5173
Real backend, real schema — this is not a zero-config demo. You need an actual Supabase project. See Backend setup below.
npm run build # tsc -b && vite build
npm run lint
npm run test # vitest — unit tests for the parsing/math-heavy logic
.env
(.env.example has the exact variable names).supabase link --project-ref <your-ref> then
supabase db push — applies every file in supabase/migrations/ in
order. There are currently 41 migrations building up the full schema
incrementally; read a few if you want the "why", not just the "what" —
this codebase documents its own reasoning unusually heavily.supabase/seed.sql once (via the SQL editor, or
supabase db reset locally) for the business-type templates and the
first launch city.supabase/functions/ (verify-login,
admin-manage-passkeys, decrypt-invite-email,
decrypt-customer-address) — supabase functions deploy <name> each, or
via the Dashboard.insert into public.platform_admins (user_id) values ('<your auth.users.id>');
supabase test db # pgTAP — requires Docker Desktop
Covers core SQL logic (booking-overlap constraint, inventory auto-decrement,
loyalty balance) and an automated tenant-isolation check. See
supabase/tests/README.md.
No passwords, no codes, no emailed links — every login page works the same
way: type your email, click Verify, and if you're authorized, register
a passkey right there (or just use your existing one on repeat visits).
See docs/REPEATLYOS_SECURITY_MODEL.md → "Bootstrap flow reworked" for
exactly how a real session is established with nothing ever shown to or
typed by the user.
Business owner:
/signup (just an unauthenticated
signup_requests row — no account exists yet)./platform-admin — this only flips
the request's status; it doesn't create an account or send anything./app, enters that same email, clicks Verify, and
registers a passkey — landing on /onboarding.status = 'pending_approval' and they're made its owner immediately.pending_approval only hides the business from the public marketplace;
it does not block the owner's own use of their dashboard.City admin: a platform admin adds their email against a city from
/platform-admin (no account needs to exist yet) — they then verify and
register a passkey at /city-admin-login. Never self-registered.
Platform admin: the one role still requiring direct SQL access
(insert into platform_admins ..., see below) — intentional friction so
this can never be granted through the app itself. Once granted, sign-in
itself works the same way, at /super-admin.
Lost your passkey or switched devices? Same flow, any role: email + Verify re-establishes a session and lets you register a new one — fully self-service, no admin involvement needed.
React 19 · TypeScript (strict) · Vite · Tailwind CSS · React Router 7 · Supabase (Postgres + Auth + Edge Functions + Storage) · Recharts · Vitest
No custom API server — Postgres Row Level Security is the actual
authorization boundary; every table has RLS enabled with policies backed by
security definer helper functions (is_business_member,
has_business_permission, is_city_admin, is_platform_admin).
repeatlyos/
├── supabase/
│ ├── migrations/ # 41 files, applied in order — the real schema
│ ├── functions/ # 4 Edge Functions (service-role-gated operations)
│ └── tests/database/ # pgTAP tests
├── src/
│ ├── App.tsx # all routes — marketplace, /app, /dashboard, admin
│ ├── lib/ # smartSearch, geo, currency, i18n, checkout, offlineQueue
│ ├── pages/
│ │ ├── marketplace/ # public shopper-facing pages
│ │ ├── business/ # real merchant dashboard (Supabase-backed)
│ │ ├── admin/ # platform + city admin
│ │ ├── onboarding/ # business registration wizard
│ │ ├── auth/ # signup, per-role sign-in pages, passkeys
│ │ └── dashboard/ # legacy mock demo — see note at the top
│ └── types/domain.ts # hand-written mirror of the SQL schema
└── docs/ # architecture, security model, progress log —
# read these for the "why" behind non-obvious decisions
delivery_pool_members and
delivery_groups model shared delivery coordination internally, but
dispatching an actual rider needs a specific local courier chosen (a
business decision, not a code one).supabase/tests/), not exhaustive
coverage of all 33 tables.cities is a normal table, not a hardcoded list), not a code change.See docs/REPEATLYOS_PROGRESS.md for the full, dated history of what was
built, tested, and found along the way.