smooth-app
전 세계 식품의 성분·영양·정보를 자유롭게 협업하고 공개하는 데이터베이스
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기medicard67-spec/nfc-medicard
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A secure clinical data portal built to accompany the NFC MediCard FYP report. Three role-based
portals (Patient, Doctor, Admin) built on:README 전문 보기 ↗A secure clinical data portal built to accompany the NFC MediCard FYP report. Three role-based portals (Patient, Doctor, Admin) built on:
.github/workflows/ci.yml).| Video | What it shows |
|---|---|
| Overview (1:30) | What NFC MediCard is and how it works, in one compilation |
| Patient demo (1:32) | A patient's journey: card registration, check-in, the doctor's tap, and the patient app |
| Doctor walkthrough (1:18) | Dashboard, appointments, admissions and discharge, medication renewals, labs and imaging, referrals, and the tablet + USB reader |
| Admin walkthrough (1:12) | Hospital dashboard, adding patients and assigning cards, check-in queue and rooms, doctor accounts, data entry, reports, and the audit log |
supabase/schema.sql,
and run it. This creates all the tables (profiles, patients, doctors,
medical_history, lab_results, radiology, messages, appointments, vitals,
audit_log) with Row Level Security enabled and no client-facing policies — all access goes
through the backend's service-role key.
supabase/migration_002_audit_and_unread.sql
instead to pick up the new audit_log table and the messages.read column.npm run seed are still pre-confirmed regardless of this setting, so seeding and
local testing aren't affected either way.
Storage buckets (lab-results, radiology) are created automatically the first time the backend
starts — no manual setup needed.
cd server && cp .env.example .env
Edit server/.env and fill in SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.
cd ../client && cp .env.example .env
Edit client/.env and fill in VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY (the anon key,
not the service role key).
cd server && npm install
cd ../client && npm install
From /server, with your .env filled in:
npm run seed
This creates demo accounts and sample clinical data directly in your Supabase project. Demo logins
(password for all: password123):
| Role | Notes | |
|---|---|---|
| Admin | [email protected] | |
| Doctor | [email protected] | Dr. Sarah Jenkins — Cardiology |
| Doctor | [email protected] | Dr. Robert Chan — Endocrinology |
| Patient | [email protected] | Card UID: 0443FADB3D0289 |
| Patient | [email protected] | Card UID: 07D8E9F0 |
Terminal 1 — Backend (from /server):
npm run dev
Runs on http://localhost:4001.
Terminal 2 — Frontend (from /client):
npm run dev
Runs on http://localhost:5173. Log in with any of the demo accounts above.
0443FADB3D0289 to pull up the seeded patient's full record.AABBCCDD) to register a brand-new
patient and bind it to that "card".jspdf)./api/doctor/stats.From /server:
npm test
Runs the Vitest + Supertest suite (auth middleware, patient CRUD, NFC lookup) against a mocked Supabase client — no real database or network access needed. The same command runs automatically on every push/PR via GitHub Actions.
nfc-medicard/
├── .github/workflows/ci.yml # Runs backend tests + frontend build on push/PR
├── docs/videos/ # Overview, patient demo, doctor and admin walkthroughs
├── supabase/
│ ├── schema.sql # Full schema + RLS (fresh setup)
│ └── migration_002_audit_and_unread.sql # Incremental migration (existing projects)
├── server/ # Express API (Supabase service-role client)
│ ├── test/ # Vitest + Supertest suite, mocked Supabase client
│ └── src/
│ ├── routes/ # patients, medical-history, lab-results, radiology,
│ │ # messages, nfc, appointments, admin, doctor, audit, users
│ ├── middleware/auth.js # verifies Supabase JWTs
│ ├── lib/ # supabase client, storage upload helper, audit log helper
│ └── seed.js
└── client/ # React app
└── src/
├── pages/{patient,doctor,admin}/
├── components/{MonthCalendar,QrCodeCard,QrScannerView}.jsx
├── context/{AuthContext,ThemeContext,ToastContext,UnreadContext}.jsx
└── lib/{supabase.js,api.js,webNfc.js,exportPdf.js}
All data access goes through the Express backend, which uses the Supabase service role key
(bypasses Row Level Security). The frontend only ever holds the anon key, used solely for
Supabase Auth (sign-in), and calls the backend with the resulting access token in the
Authorization: Bearer <token> header. The backend's own middleware (requireAuth /
requireRole) enforces who can see and modify what. Key mutating actions (registrations, NFC
scans, record/lab/imaging additions) are recorded to audit_log for accountability.
This deploys the frontend to Vercel (free) and the backend to Render (free tier), both connected to a GitHub repo so every push auto-deploys.
git init # if not already a repo
git add .
git commit -m "Initial commit"
Create a new empty repository on github.com/new, then:
git remote add origin <your-repo-url>
git branch -M main
git push -u origin main
server.npm install, start command npm start (or let Render auto-detect from
package.json).SUPABASE_URLSUPABASE_SERVICE_ROLE_KEYCLIENT_ORIGIN — set this after step 2 below, to your Vercel URL (comma-separate if you add
more origins later, e.g. https://app.vercel.app,https://yourdomain.com)PORT automatically — no need to add it.https://<something>.onrender.com URL — that's your VITE_API_URL base for the frontend
(append /api).client.npm run build, output dist
(defaults are correct).VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYVITE_API_URL — https://<your-render-app>.onrender.com/apihttps://<something>.vercel.app URL.Go back to Render and set CLIENT_ORIGIN to the Vercel URL from step 2 (this is what CORS checks
against), then redeploy the backend service so the change takes effect.
Your site is now live at the Vercel URL — share that with anyone to let them use the app.
The same React codebase can be wrapped into a native Android app with
Capacitor — no rewrite, no separate mobile codebase. The website keeps
working exactly as before; this just adds an installable .apk on top. (iOS isn't covered here —
building an iOS app requires Xcode, which only runs on macOS.)
Already set up in this repo:
client/capacitor.config.json — app id com.medicard.nfc, web dir dist.client/.env.production — overrides VITE_API_URL to point at the deployed Render backend
(instead of localhost) whenever npm run build runs, so the packaged app talks to production.client/android/ — the generated native Android project (gitignored: .gradle/, build/,
local.properties, and any local JDK under .tools/).cd client
npm run build # bundles the app with the production API URL baked in
npx cap sync android # copies the fresh web build into the native project
Then open the client/android folder in Android Studio, let Gradle sync, and go to
Build → Build Bundle(s) / APK(s) → Build APK(s). The resulting .apk can be sideloaded
directly onto any Android device — no Play Store submission needed.
Capacitor's Android WebView serves the app from the origin https://localhost. Add that to the
backend's CLIENT_ORIGIN environment variable on Render (comma-separated alongside the Vercel
URL) so the packaged app's API calls aren't rejected by CORS:
https://nfc-medicard-5y8u.vercel.app,https://localhost
For presenting somewhere with unreliable or no internet, there's a fully self-contained offline build — no Supabase, no Render, no Vercel, nothing outside your own laptop:
cd client && npm run build:offline # builds client/dist-offline against a local API
cd ../server && npm run offline # serves the app + a canned in-memory dataset on one port
Open http://localhost:4444 — same demo accounts as above ([email protected],
[email protected], [email protected] / password123, card UID 0443FADB3D0289). You can
disconnect Wi-Fi entirely and it keeps working: server/offline-server.js is a single Express
process serving both the built frontend and an in-memory stand-in for the API, seeded with the
same demo data as npm run seed. It's for a local demo only — the auth "token" it issues has no
real security, so never deploy this file or expose it beyond your own machine.
supabase.storage.from(bucket).createSignedUrl()).