Hallo Stroke

Database Schema

PostgreSQL schema — core tables and relationships.

PostgreSQL 18 via GORM. cmd/main.go runs AutoMigrate against all models on startup. init.sql enables the uuid-ossp extension and declares enum types.

Entity relationships

Loading diagram...

Core tables

users

FieldTypeNotes
usernamevarcharunique
emailvarcharunique, nullable
passwordvarcharbcrypt hash, hidden in responses
nikvarcharunique, AES-GCM encrypted
nama_ktpvarcharfull legal name
nama_samaranvarcharforum pseudonym
nomor_hpvarcharunique, normalized to 62-prefix
rolevarchar(20)default "user"; "admin" for admins
preferencestext[]content/religion categories
refresh_tokenvarcharstored JWT refresh
timezonevarchardefault "Asia/Makassar"
is_verifiedbool
password_reset_tokenuuidnullable

pengingats (reminders)

FieldTypeNotes
user_iduint FKcascade
tipevarchar(20)obat / makan / kontrol / terapi
judulvarchar(100)
waktutimeindexed with user_id
timezonevarchar
is_donebool
is_sentbooltrue when all schedules sent
detailsJSONBschedule array + per-schedule send state

Composite index idx_userid_waktu.

forum_threads / forum_replies

Threads and replies both support image_url, use_pseudonym, likes (composite-PK join tables), and saves. Replies nest via nullable parent_id.

Content tables

  • articles — scraped from Kemenkes or manually added; url unique, tag JSON, FK to kategoris.
  • videos / video_details — YouTube catalog; video_id unique.
  • saved_articles / saved_videos — composite-PK (user_id, article_url|video_id).

faskes / dokters

  • faskesplace_id (Google) unique, lat/lng, status_operasional.
  • dokters — many2many to faskes via dokter_faskes; jadwal_praktik stored as JSONB array.

Logging

log_users and log_admins use UUID primary keys (uuid_generate_v4()), are written via an async queue, and carry rich analytics fields (event_type, event_name, screen_name, activity, action_status, error_message).

Known schema inconsistency

init.sql declares enum types role_display_type, reminder_status, reminder_type, while database/enum.go separately creates a kategori_type enum at startup. The in-code KategoriType Scan/Value methods treat it as a plain string, so the dynamic kategoris table is what articles/videos actually FK-link to.

On this page