mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 11:12:56 +00:00
dev day #92
This commit is contained in:
@@ -0,0 +1,378 @@
|
||||
%%{init: {"theme":"forest","flowchart":{"curve":"linear"},"themeCSS":"svg { font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; } .edgePath path { stroke-dasharray: 6 4; animation: dash 16s linear infinite; } .animated-edge path { stroke-dasharray: 6 4; animation: dash 16s linear infinite; } @keyframes dash { to { stroke-dashoffset: -1000; } } .ext > rect, .ext > polygon, .ext > path { stroke: #7e57c2; } .db > rect, .db > polygon, .db > path { fill: #e3f2fd; stroke: #1e88e5; } .svc > rect, .svc > polygon, .svc > path { fill: #e8f5e9; stroke: #43a047; } .fe > rect, .fe > polygon, .fe > path { fill: #fff8e1; stroke: #f9a825; } .ctrl > rect, .ctrl > polygon, .ctrl > path { fill: #f3e5f5; stroke: #8e24aa; } .mid > rect, .mid > polygon, .mid > path { fill: #e0f2f1; stroke: #00897b; } .model > rect, .model > polygon, .model > path { fill: #ede7f6; stroke: #5e35b1; } .route > rect, .route > polygon, .route > path { fill: #e8eaf6; stroke: #3f51b5; }" }}%%
|
||||
flowchart TB
|
||||
|
||||
%% ========================= Docker & Runtime =========================
|
||||
subgraph DOCKER["Docker Compose (Local Dev/Prod)"]
|
||||
direction TB
|
||||
docker_net([Bridge Network: fotbal-network]):::svc
|
||||
docker_vol1["Volume: postgres_data"]:::svc
|
||||
docker_vol2["Bind: ./uploads -> /app/uploads"]:::svc
|
||||
docker_vol3["Bind: ./cache -> /app/cache"]:::svc
|
||||
|
||||
subgraph docker_backend["backend (Go) container"]
|
||||
direction TB
|
||||
be_8080["Expose 8080:8080"]
|
||||
be_env[".env + overrides"]
|
||||
be_cmd["command: ./main"]
|
||||
end
|
||||
|
||||
subgraph docker_frontend["frontend (Nginx) container"]
|
||||
direction TB
|
||||
fe_3000["Expose 3000:80"]
|
||||
fe_env[".env.frontend"]
|
||||
end
|
||||
|
||||
subgraph docker_db["postgres:15-alpine"]
|
||||
direction TB
|
||||
db_5432["Expose 5432:5432"]
|
||||
db_env["POSTGRES_* env"]
|
||||
end
|
||||
|
||||
docker_net --- docker_backend
|
||||
docker_net --- docker_frontend
|
||||
docker_net --- docker_db
|
||||
docker_vol1 --- docker_db
|
||||
docker_vol2 --- docker_backend
|
||||
docker_vol3 --- docker_backend
|
||||
end
|
||||
|
||||
user_browser((User Browser)):::ext
|
||||
user_browser ==>|HTTP 80| docker_frontend:::animated-edge
|
||||
user_browser -.->|dev direct (HTTP 8080)| docker_backend
|
||||
|
||||
%% ========================= Backend (Go/Gin) =========================
|
||||
subgraph BACKEND["Backend Service (Golang + Gin) :8080"]
|
||||
direction TB
|
||||
cfg[Config (internal/config.Config)\n- APP_ENV/PORT/DEBUG\n- DATABASE_URL (GORM)\n- JWT_SECRET/EXP\n- ALLOWED_ORIGINS (CORS)\n- UPLOAD_DIR/MAX_UPLOAD_SIZE\n- SMTP_* (Email)\n- FRONTEND_BASE_URL\n- PUBLIC_API_BASE_URL\n- ERROR_INGEST_URL/TOKEN\n- FACR_SCRAPER_BASE_URL\n- UMAMI_*\n- CLAMAV_* (optional)]
|
||||
logger[Logger (pkg/logger)]
|
||||
db_init[[InitDB() + AutoMigrate()]]:::db
|
||||
email_svc[EmailService (pkg/email)]:::svc
|
||||
|
||||
subgraph middleware[Middleware]
|
||||
direction TB
|
||||
mw_reqid[RequestID]
|
||||
mw_logger[RequestLogger]
|
||||
mw_recovery[CustomRecoveryWithReporter]
|
||||
mw_errstatus[ErrorStatusReporter]
|
||||
mw_sanitize[SanitizeHeaders]
|
||||
mw_dbctx[DBContext (req ctx timeout)]
|
||||
mw_size[RequestSizeLimit (2MB)]
|
||||
mw_ct[ValidateContentType]
|
||||
mw_csrf[CSRFProtection (protected)]
|
||||
mw_rate[RateLimit (per-route)]
|
||||
mw_sec[SecurityHeaders + AssetCacheControl]
|
||||
end
|
||||
|
||||
prometheus["GET /metrics (promhttp)"]
|
||||
static1["Static: /uploads -> UPLOAD_DIR"]
|
||||
static2["Static: /cache -> ./cache"]
|
||||
static3["Static: /dist -> ./static"]
|
||||
static4["Static: /premium-assets -> ./pro"]
|
||||
|
||||
subgraph router["Router"]
|
||||
direction TB
|
||||
api_grp["/api/v1"]:::route
|
||||
root_grp["/root/"]:::route
|
||||
end
|
||||
|
||||
subgraph controllers[Controllers]
|
||||
direction TB
|
||||
c_auth[AuthController\n/login,/logout,/register,/me\n/password-reset]
|
||||
c_contact[ContactController\n/contact + newsletter + admin forwarding]
|
||||
c_pass[PasswordController]
|
||||
c_ai[AIController\n/ai/blog,/ai/about,/ai/css,/ai/instagram]
|
||||
c_score[ScoreboardController\n/public + admin timer/sponsors/qr]
|
||||
c_about[AboutController]
|
||||
c_gallery[GalleryController\n/Zonerama profile/albums/picks]
|
||||
c_files[FilesController\n/list/unused/duplicates/usage\n/scan/refresh-tracking/delete]
|
||||
c_notify[NotificationsController]
|
||||
c_email[EmailController\n/open.gif/click/unsubscribe/stats]
|
||||
c_prefetch[PrefetchController\n/status/trigger]
|
||||
c_seo[SEOController\n/seo (public) + robots.txt + sitemap]
|
||||
c_nav[NavigationController\n/navigation + social-links + admin CRUD]
|
||||
c_poll[PollController\n/public vote/results + admin]
|
||||
c_sw[SweepstakesController\n/public current/visual + admin CRUD/finalize]
|
||||
c_cloth[ClothingController\n/public + admin CRUD]
|
||||
c_pec[PageElementConfigController\n/public + admin CRUD/batch]
|
||||
c_article[ArticleController\n/create + match-link]
|
||||
c_base[BaseController\n/health, uploads, categories, teams, players, matches, standings, zonerama, settings, shortlinks(public)]
|
||||
c_myu[MyUIbrixController\n/validate,/preview,/optimize]
|
||||
c_editor[EditorPreviewController\n/preview state + variants]
|
||||
c_short[ShortLinkController\n/public create + admin + redirect /s/:code]
|
||||
c_comment[CommentController\n/public list + CRUD + reactions\nban/unban/report (admin)]
|
||||
c_eng[EngagementController\n/rewards/leaderboard/profile/actions]
|
||||
c_facr[FACRController\n/facr club search/info/table]
|
||||
c_yt[YouTubeController\n/youtube/videos]
|
||||
c_umami[UmamiController\n/config + admin initialize/stats]
|
||||
c_error[ErrorController\n/errors ingest + admin + external]
|
||||
end
|
||||
|
||||
subgraph services[Services & Jobs]
|
||||
direction TB
|
||||
s_errrep[ErrorReporter]
|
||||
s_prefetch[Prefetcher\nStartPrefetcher(target)]
|
||||
s_nlsched[NewsletterScheduler]
|
||||
s_nlauto[NewsletterAutomation\nweekly, reminders, results]
|
||||
s_sweep[SweepstakesScheduler]
|
||||
s_umami[UmamiService]
|
||||
s_facr[FACRService]
|
||||
s_cache[CacheService]
|
||||
s_logo[LogoCache]
|
||||
s_filetrk[FileTracker]
|
||||
s_imgopt[ImageOptimizer]
|
||||
s_bad[BadWords/Spam]
|
||||
s_setup[SetupService]
|
||||
end
|
||||
|
||||
subgraph models[Models (GORM)]
|
||||
direction LR
|
||||
m_settings[Settings]
|
||||
m_user[User]
|
||||
m_article[Article]
|
||||
m_scoreboard[ScoreboardState]
|
||||
m_compalias[CompetitionAlias]
|
||||
m_team[Team]
|
||||
m_player[Player]
|
||||
m_contact_cat[ContactCategory]
|
||||
m_contact[Contact]
|
||||
m_contact_msg[ContactMessage]
|
||||
m_news[NewsletterSubscription]
|
||||
m_sponsor[Sponsor]
|
||||
m_cloth[Clothing]
|
||||
m_poll[Poll + PollOption + PollVote]
|
||||
m_nav[NavigationItem + SocialLink]
|
||||
m_pageel[PageElementConfig]
|
||||
m_short[ShortLink + LinkClick]
|
||||
m_comment[Comment + Reaction + Ban + UnbanRequest + Report]
|
||||
m_profile[UserProfile]
|
||||
m_points[PointsTransaction]
|
||||
m_ach[Achievement + UserAchievement]
|
||||
m_reward[RewardItem + RewardRedemption]
|
||||
m_over[MatchOverride + TeamLogoOverride]
|
||||
m_sweep[Sweepstake + Prize + Entry + Winner]
|
||||
m_up[UploadedFile + FileUsage]
|
||||
m_error[ErrorEvent]
|
||||
end
|
||||
|
||||
%% wiring inside backend
|
||||
cfg --> db_init
|
||||
cfg --> email_svc
|
||||
router --> middleware
|
||||
api_grp --> controllers
|
||||
root_grp --> c_seo
|
||||
root_grp --> c_short
|
||||
api_grp --> c_auth
|
||||
api_grp --> c_contact
|
||||
api_grp --> c_pass
|
||||
api_grp --> c_ai
|
||||
api_grp --> c_score
|
||||
api_grp --> c_about
|
||||
api_grp --> c_gallery
|
||||
api_grp --> c_files
|
||||
api_grp --> c_notify
|
||||
api_grp --> c_email
|
||||
api_grp --> c_prefetch
|
||||
api_grp --> c_seo
|
||||
api_grp --> c_nav
|
||||
api_grp --> c_poll
|
||||
api_grp --> c_sw
|
||||
api_grp --> c_cloth
|
||||
api_grp --> c_pec
|
||||
api_grp --> c_article
|
||||
api_grp --> c_base
|
||||
api_grp --> c_myu
|
||||
api_grp --> c_editor
|
||||
api_grp --> c_short
|
||||
api_grp --> c_comment
|
||||
api_grp --> c_eng
|
||||
api_grp --> c_facr
|
||||
api_grp --> c_yt
|
||||
api_grp --> c_umami
|
||||
api_grp --> c_error
|
||||
|
||||
%% controllers -> models
|
||||
controllers -->|GORM| models
|
||||
db_init ==>|Postgres conn| DB["PostgreSQL :5432 / fotbal_club"]:::db
|
||||
models ==>|tables| DB
|
||||
|
||||
%% services wiring
|
||||
s_prefetch -.->|GET public endpoints| api_grp
|
||||
s_nlsched --> s_nlauto
|
||||
s_nlauto --> email_svc
|
||||
s_sweep --> email_svc
|
||||
s_filetrk --> m_up
|
||||
s_imgopt --> m_up
|
||||
s_errrep --> c_error
|
||||
s_umami --> c_umami
|
||||
s_facr --> c_facr
|
||||
email_svc -->|SMTP| smtp[(SMTP Provider)]:::ext
|
||||
|
||||
%% externals
|
||||
facr_ext["FACR Scraper :8081"]:::ext
|
||||
errors_ingest["Error Receiver: errors.tdvorak.dev/api/v1/errors or local :8083"]:::ext
|
||||
errors_admin["Error Review Admin UI/API: errors.tdvorak.dev"]:::ext
|
||||
umami_ext["Umami Analytics server"]:::ext
|
||||
|
||||
s_facr <---> facr_ext:::animated-edge
|
||||
s_errrep --> errors_ingest:::animated-edge
|
||||
c_error <---> errors_admin
|
||||
s_umami <---> umami_ext
|
||||
|
||||
%% static serving
|
||||
static1 --- user_browser
|
||||
static2 --- user_browser
|
||||
static3 --- user_browser
|
||||
static4 --- user_browser
|
||||
|
||||
%% metrics
|
||||
prometheus --- user_browser
|
||||
end
|
||||
|
||||
user_browser ==>|HTTP /api/v1| api_grp:::animated-edge
|
||||
user_browser ==>|HTTP /robots.txt, /sitemap.xml, /s/:code| root_grp
|
||||
|
||||
%% ========================= Frontend (React) =========================
|
||||
subgraph FRONTEND[Frontend (React + ChakraUI)]
|
||||
direction TB
|
||||
fe_router[React Router (src/App.tsx)]:::fe
|
||||
|
||||
subgraph fe_public[Public Pages]
|
||||
direction LR
|
||||
p_home[HomePage /]
|
||||
p_blog[BlogPage /blog]
|
||||
p_newslist[ArticlesListPage]
|
||||
p_article[ArticleDetailPage /news/:slug | /articles/:id]
|
||||
p_about[AboutPage /o-klubu]
|
||||
p_club[ClubPage /klub]
|
||||
p_calendar[CalendarPage /kalendar]
|
||||
p_actcal[ActivitiesCalendarPage /aktivity]
|
||||
p_tables[TablesPage /tabulky]
|
||||
p_matches[MatchesPage /zapasy]
|
||||
p_match[MatchDetailPage /zapas/:id]
|
||||
p_players[PlayersPage /hraci]
|
||||
p_player[PlayerDetailPage /hraci/:id]
|
||||
p_sponsors[SponsorsPage /sponzori]
|
||||
p_contact[ContactPage /kontakt]
|
||||
p_gallery[GalleryPage /galerie]
|
||||
p_album[AlbumDetailPage /galerie/album/:id]
|
||||
p_videos[VideosPage /videa]
|
||||
p_clothing[ClothingPage /obleceni]
|
||||
p_polls[PollsPage /ankety]
|
||||
p_search[SearchPage /hledat]
|
||||
p_short[ShortRedirectPage /s/:code]
|
||||
p_over_sb[OverlayScoreboardPage /overlay/scoreboard]
|
||||
p_over_sp[OverlaySponsorsPage /overlay/sponsors]
|
||||
p_cookies[CookiePolicyPage]
|
||||
p_terms[TermsPage]
|
||||
p_privacy[PrivacyPolicyPage]
|
||||
p_notfound[NotFoundPage *]
|
||||
end
|
||||
|
||||
subgraph fe_auth[Auth & Setup]
|
||||
direction LR
|
||||
p_login[AuthPage /login]
|
||||
p_register[RegisterPage /register]
|
||||
p_forgot[ForgotPasswordPage /forgot-password]
|
||||
p_reset[ResetPasswordPage /reset-password]
|
||||
p_setup[SetupPage /setup]
|
||||
p_style[StylePreviewPage /setup/styl]
|
||||
p_news_unsub[NewsletterUnsubscribePage]
|
||||
p_news_prefs[NewsletterPreferencesPage]
|
||||
end
|
||||
|
||||
subgraph fe_admin[Admin Pages]
|
||||
direction LR
|
||||
a_dashboard[AdminDashboardPage]
|
||||
a_docs[AdminDocsPage]
|
||||
a_about[AboutAdminPage]
|
||||
a_videos[AdminVideosPage]
|
||||
a_gallery[GalleryAdminPage]
|
||||
a_merch[AdminMerchPage]
|
||||
a_sponsors[SponsorsAdminPage]
|
||||
a_matches[MatchesAdminPage]
|
||||
a_players[PlayersAdminPage]
|
||||
a_teams[TeamsAdminPage]
|
||||
a_users[UsersAdminPage]
|
||||
a_banners[BannersAdminPage]
|
||||
a_messages[MessagesAdminPage]
|
||||
a_settings[SettingsAdminPage]
|
||||
a_newsletter[NewsletterAdminPage]
|
||||
a_polls[PollsAdminPage]
|
||||
a_comp[CompetitionAliasesAdminPage]
|
||||
a_prefetch[PrefetchAdminPage]
|
||||
a_scoreboard[ScoreboardAdminPage]
|
||||
a_score_remote[MobileScoreboardControlPage]
|
||||
a_analytics[AnalyticsAdminPage]
|
||||
a_shortlinks[ShortlinksAdminPage]
|
||||
a_files[FilesAdminPage]
|
||||
a_contacts[ContactsAdminPage]
|
||||
a_navigation[NavigationAdminPage]
|
||||
a_comments[CommentsAdminPage]
|
||||
a_engagement[EngagementAdminPage]
|
||||
a_sweep[SweepstakesAdminPage]
|
||||
a_sweep_visual[SweepstakeVisualPage]
|
||||
a_adminreset[AdminResetPasswordPage]
|
||||
end
|
||||
|
||||
%% FE -> BE API mappings (high level)
|
||||
fe_router -->|services/api.ts| api_grp:::animated-edge
|
||||
p_blog -->|GET /articles| api_grp
|
||||
p_article -->|GET /articles/slug/:slug, /articles/:id\nPOST /articles/:id/read| api_grp
|
||||
p_home -->|GET /articles/featured, /matches, /standings, /settings, /navigation| api_grp
|
||||
p_matches -->|GET /matches,/standings| api_grp
|
||||
p_match -->|GET /matches/:id| api_grp
|
||||
p_players -->|GET /players| api_grp
|
||||
p_player -->|GET /players/:id| api_grp
|
||||
p_gallery -->|GET /gallery/albums| api_grp
|
||||
p_album -->|GET /gallery/albums/:id| api_grp
|
||||
p_videos -->|GET /youtube/videos| api_grp
|
||||
p_clothing -->|GET /clothing| api_grp
|
||||
p_polls -->|GET /polls| api_grp
|
||||
p_contact -->|POST /contact| api_grp
|
||||
p_over_sb -->|GET /scoreboard (public)| api_grp
|
||||
p_over_sp -->|GET /scoreboard/sponsors| api_grp
|
||||
p_short -->|GET /s/:code (root)| root_grp
|
||||
|
||||
%% Admin flows
|
||||
a_articles[ArticlesAdminPage] -->|POST/PUT/DELETE /articles\n/link-match| api_grp
|
||||
a_matches -->|GET /admin/matches| api_grp
|
||||
a_comments -->|GET/PATCH /admin/comments| api_grp
|
||||
a_navigation -->|CRUD /admin/navigation| api_grp
|
||||
a_files -->|GET/DELETE /admin/files| api_grp
|
||||
a_scoreboard -->|GET/PUT /admin/scoreboard + timer| api_grp
|
||||
a_score_remote -->|POST timer controls| api_grp
|
||||
a_newsletter -->|send/test/preview/status| api_grp
|
||||
a_sweep -->|CRUD /admin/sweepstakes| api_grp
|
||||
a_sweep_visual -->|GET /admin/sweepstakes/:id/visual| api_grp
|
||||
a_analytics -->|/admin/umami| api_grp
|
||||
|
||||
%% FE error reporting & analytics
|
||||
fe_router -->|POST /errors (ErrorReporter)| api_grp:::animated-edge
|
||||
fe_router -->|GET /umami/config| api_grp
|
||||
|
||||
end
|
||||
|
||||
%% ========================= Ports & CORS =========================
|
||||
subgraph PORTS[Ports & CORS]
|
||||
direction LR
|
||||
port_be[Backend :8080]
|
||||
port_fe[Frontend :3000 -> :80]
|
||||
port_db[Postgres :5432]
|
||||
cors[CORS AllowedOrigins\n- http://localhost:3000\n- http://localhost:8080\n+ FrontendBaseURL origin\n+ "*" optional in dev]
|
||||
end
|
||||
port_be --- docker_backend
|
||||
port_fe --- docker_frontend
|
||||
port_db --- docker_db
|
||||
cors -. controls .- router
|
||||
|
||||
%% Legend
|
||||
subgraph LEGEND[Legend]
|
||||
direction LR
|
||||
L1[External Service]:::ext
|
||||
L2[Database/Table]:::db
|
||||
L3[Service/Daemon]:::svc
|
||||
L4[Controller]:::ctrl
|
||||
L5[Middleware]:::mid
|
||||
L6[Model]:::model
|
||||
L7[Route Group]:::route
|
||||
end
|
||||
Reference in New Issue
Block a user