Commit Graph

21 Commits

Author SHA1 Message Date
chpark 291f8bc20d Header dropdown menu visibility fix: inline color #1f2937 + JS hover fallback
The mega-menu sub-panel was rendering with invisible text on some browsers
(Tailwind class chain in v4 + framer-motion mount-time race). Switching to
inline style locks the contrast regardless of CSS-class resolution order:

- panel motion.div: explicit background:#ffffff + color:#1f2937 + z-50
- each sub-link: inline color:#1f2937 (default) and white-on-violet hover
  pushed via onMouseOver/Out as a JS fallback
- top-level mega-menu link already had explicit color:#fff with text shadow

This is defensive — no harm if Tailwind already handled it; corrects any
case where the panel showed empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 18:32:16 +09:00
chpark d008a28a82 Per-board admin (92 columns) + flexible runtime: bo_page_rows / bo_subject_len / bo_*_point applied
/admin/boards/[bo_table]/edit:
- Full form for every editable g5_board column gnuboard exposes
  in /adm/board_form.php (92 columns):
  - basic info (group/skin/device/admin/editor)
  - 10 permission levels (list/read/write/reply/comment/upload/download/html/link/poll)
  - 4 point fields (read/write/comment/download)
  - listing & gallery (page rows, subject len, HOT/N, gallery cols/w/h, mobile variants)
  - 23 feature toggles (secret/good/nogood/name/sig/ip/search/email/sns/captcha/category/sideview/file-content/approval...)
  - upload limits (count/size/min/max length for write+comment)
  - header/footer HTML, mobile variants, fixed-notice list
  - bo_1..bo_10 + bo_*_subj custom slots
- Submitted as a single transaction to UPDATE g5_board

Runtime application (the actual flex-knob behaviour):
- listPosts now reads bo_page_rows (5–200) and bo_subject_len from g5_board for each list render
- addComment now also pays bo_comment_point bonus into g5_point ledger and bumps mb_point
- Post view (board/[wrId]) now charges/credits bo_read_point once per (mb_id, post)
  with @read.<key> dedupe row in g5_point — same semantics as gnuboard

Also: /admin/boards now shows a "상세설정" link per row.

Verify: 10 iter × 102 = 1020/1020 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 13:46:28 +09:00
chpark a271ce0bb1 Complete admin: 35 more pages → 80 menus all reachable (read + 50+ full-CRUD)
Code-generated 30 list-style admin pages via SimpleListAdmin component:
  eyoom: themes/config/boards/shopmenu/ebslider/ebcontents/eblatest/ebbanner/level/memo/activity
  plugin: chatbot/chatbot-feedback
  sms: hp-group/hp/emoticon-group/emoticon/history-num
  members: visit-search/funnels/mail
  boards: parsing/wrfixed/popular-rank
  shop: item-options/item-events/personalpay/stocksms
  roulette: rewards/chances

Hand-written 8 action / config admin pages:
  /admin/plugin/board-manage (per-board hit-reset / 날짜→현재 bulk)
  /admin/plugin/browscap (mock refresh)
  /admin/plugin/visit-convert (g5_visit → g5_visit_sum re-aggregate)
  /admin/sms/member-update (sync mb_hp into sms5_book)
  /admin/sms/hp-file (bulk text-paste import)
  /admin/members/visit-delete (purge g5_visit older than N days)
  /admin/members/point-compress (purge g5_point older than N days)
  /admin/boards/qa-config (g5_qa_config single-row form)
  /admin/boards/write-count (per-board bo_count_write/comment table)
  /admin/shop/examount (coupon-log aggregation by member)
  /admin/shop/expoint (point-spend aggregation from g5_point @shop_order)

Helpers:
- lib/admin-write.ts (requireAdmin, deleteByPk)
- components/admin/SimpleListAdmin.tsx (reusable header+table)

Verify: 10 iter × 102 = 1020/1020 PASS (cross-verify now walks ~80 admin URLs)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:38:42 +09:00
chpark 2e4f07442a V4 cinematic Hero + glass + hover contrast fix; verify 3050/3050
Hero V4:
- Full-bleed mesh-cinematic background (4 radial color blobs + grid + animated conic aurora)
- Headline: 64px black weight, hue-sliding gradient text (8s loop)
- 3 floating glow orbs animated at 7s intervals
- 4 CTA pills: 보증 (white), 먹튀 (rose), 슬생TV (glass), 슬생복권 (gradient amber)
- KICK status card → glass panel with tilt-on-hover + green CTA glow

Header hover:
- top-level menu: explicit color:#fff + textShadow + z-10 (so the conic aurora can't bleed over text)
- hover:bg-black/25 (was bg-white/10) + yellow underline shadow indicator
- font-extrabold instead of font-semibold

CSS additions (globals.css):
- .bg-mesh-cinematic, .glass, .text-hue, .tilt, .orb classes
- new keyframes: orb-float, hue-slide

Verify: 50 iter × 61 = 3050/3050 PASS (already with all 38 admin walks)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:20:09 +09:00
chpark ce98dcaf27 Customizable home layout + 11 more admin pages (45 admin total now)
Home layout (gnuboard-style widget configurator):
- /admin/eyoom/main-layout: toggle each section, set order, edit board slugs
- public.app_settings.home_layout = { sections: [{ id, enabled, order, boards }] }
- app/page.tsx reads layout, renders sections in admin-defined order
- getFeaturedBoards now accepts override slug list (admin-controlled featured boards)
- 7 toggleable widgets: hero, statStrip, topWinners, hotBoards, quickAccess, boardSlots, liveActivity

Shop admin (영카트):
- /admin/shop/brands: brand-grouped item counts
- /admin/shop/couponzone: coupon-zone create/delete
- /admin/shop/buylist: per-member purchase totals (mb_id, count, sum)

Members admin:
- /admin/members/visits: 60-day bar chart (g5_visit_sum)
- /admin/members/poll: g5_poll create / toggle use

Boards admin:
- /admin/boards/popular: 30-day search-keyword heatmap (g5_popular)

Eyoom admin:
- /admin/eyoom/tags: g5_eyoom_tag menu-display toggle / delete
- /admin/eyoom/attendance: top 100 attendance + 30 latest

SMS admin:
- /admin/sms/history: paginated 50/page sms5_history

SEO:
- /admin/seo: ask_seo_url meta CRUD

verify-cross: now exercises 38 admin URLs as admin (was 27)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:16:34 +09:00
chpark a096903dea verify-cross: PHP admin + React admin parity walks (50 admin URLs each iter)
Cross-verify now logs in as admin on BOTH stacks and walks the admin tree:
- PHP: /adm/, config_form, board_list, member_list (admin/clone1234)
- React: /admin + 27 sub-pages (admin/test1234) covering every page that has
  full-CRUD wired (members/boards/themes/config/shop/eyoom/sms/plugin/roulette/lottery)

Result: each iter now runs ~50 checks (16 user + 34 admin). 5×50 = 250 PASS.
Catches: any admin page reachability regression, auth-guard breakage, 500s,
missing routes, broken queries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 11:53:40 +09:00
chpark 74fe7f3557 Admin: config auth/maintenance/clean, boards/groups, shop config/cat/coupon/orders, eyoom mgr/biz
10 new full-CRUD admin pages mirroring gnuboard's PHP admin:
- /admin/config/auth (g5_auth) — sub-admin permission grants/revokes
- /admin/config/maintenance — site-wide maintenance toggle (app_settings.maintenance)
- /admin/config/clean — 4 cleanup jobs (sessions / visit / login / point compress)
- /admin/boards/groups (g5_group) — create/rename/delete board groups
- /admin/shop/config (g5_shop_default) — store-wide settings
- /admin/shop/categories (g5_shop_category) — product categories CRUD
- /admin/shop/coupons (g5_shop_coupon) — coupon issuance, fixed/% method
- /admin/shop/orders — paginated order list with status change (입금완료/배송 etc)
- /admin/eyoom/managers (g5_eyoom_manager) — appoint/dismiss
- /admin/eyoom/biz-info (app_settings.biz_info) — company / CEO / 사업자번호

Verify: 50 iter × 16 = 800/800 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 11:40:22 +09:00
chpark 505398ec9f Board access guard, tag page real impl, rankings PHP-parity, freespin, more admin
Board access (mirrors gnuboard bo_read/write/comment_level):
- legacy-board.ts: getBoardMeta now returns readLevel/writeLevel/commentLevel/useSecret/useCert
- checkBoardAccess(meta, userLevel, action) helper used on:
  /[boardSlug] (read), /[boardSlug]/[wrId] (read), /[boardSlug]/write (write)
- Insufficient level → friendly lock screen with "필요 Lv.X" + login redirect for anon

Tag indexing (real):
- /tag/[tag]: pulls from inspection2.g5_eyoom_tag_write (cached subject/hit/datetime)
- ILIKE wr_tag, paginated 20 per page, total count in header
- highlights matched tag; lists other tags on each post

Rankings PHP-parity (lib/member.rank.lib.php):
- NOT IN ('admin','admin2','admin3','admin4','roy')
- mb_point > 0 AND mb_level < 11
- LEFT JOIN g5_eyoom_member.level (이윰 레벨)
- ORDER BY mb_point DESC
- Both sidebar getMemberRankings and home TopWinners switched
- Visible result: 보내드림 1.66M / 코뚜롱 1.48M / 스티브박 1.40M (admin* hidden)

Freespin (game engine):
- inspection2.app_freespin (mb_id, slug, remaining)
- Scatter ≥3 grants 5-10 free spins
- Next spin uses bet=0; remaining-- recorded transactionally
- placeBetAndSpin returns freeSpinsRemaining

Admin write:
- /admin/plugin/recaptcha (saved into public.app_settings)
- /admin/roulette (g5_roulette_list rename/delete + reward list)
- /admin/lottery/winners (lottery_history, paginated 50)

Verify: 50 iter × 16 = 800/800 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:05:20 +09:00
chpark 782029d31f memo CRUD, admin yellowcard/sns/sms-write, scatter free-spin, theme-skinned mega
User pages:
- /memo: inbox/sent tabs with send + delete server actions on g5_memo
  (creates paired recv+send rows so both sides can delete independently)

Admin:
- /admin/eyoom/yellowcard: issue/withdraw warnings (g5_eyoom_yellowcard)
- /admin/plugin/sns: 4 OAuth providers (Naver/Kakao/Facebook/Google),
  saved into public.app_settings with social_<provider> keys
- /admin/sms/write: mock SMS send + recent 30 from sms5_history

Game engine:
- scatter symbol with 5% spawn rate
- 3+ scatters trigger free-spin (no bet deducted, message + flag)
- 88포춘: wild=🌟, scatter=🎁

Theme skinning (basic/amina/youngcart variants of):
- .bg-mega gradient (mega-menu nav)
- .bg-brand-radial (Hero aurora) — basic blue, amina cyan, youngcart orange
- root layout writes data-theme="..." attribute

Verify: 50 iter × 16 = 800/800 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 18:11:28 +09:00
chpark 0d248eb6ae React standalone on :8088, mypage tabs, sms config, wild symbols, cross-verify x16
Standalone deployment:
- React Next.js no longer uses basePath; served directly at port 8088
- nginx slot-react vhost on listen 8088 proxies / -> 127.0.0.1:3000
- 80 default vhost simplified to PHP-only (no /react path)
- ufw allow 8088/tcp

User pages:
- /mypage/follower (g5_eyoom_follow target_id=mb_id)
- /mypage/following (g5_eyoom_follow mb_id=mb_id)
- /mypage/activity (g5_eyoom_activity + g5_point ledger)
- /mypage/password (verifyLegacyPassword + hashPassword)

Admin:
- /admin/sms/config (sms5_config single-row CRUD)

Game engine:
- Wild symbol with 7% spawn rate, substitutes for any in 3-of-a-kind
- Wild count multiplier: payout = base × (1 + wildCount × 0.5)

Verify-cross: now tests
  PHP: home, board, login, /adm/
  React: home, board, login, mypage, shop, games/play
  Cross: robots.txt block on both
  Theme cookie: 4 themes (basic/eyoom/amina/youngcart) round-trip
50 iterations × 16 = 800/800 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 14:53:58 +09:00
chpark 4e6a304615 React behind /react basePath; nginx restores 80 to PHP; cross-verify suite
Co-existence on 201: 80=PHP gnuboard5 (default vhost), /react=Next.js (basePath)
- Dockerfile takes ARG NEXT_PUBLIC_BASE_PATH, passes to Next build for asset/route prefixing
- next.config.mjs reads NEXT_PUBLIC_BASE_PATH at build time
- nginx slot-clone vhost: location /react proxies to 3000 unchanged; / and /adm/ go to 8090
- /robots.txt remains nginx-served (all-bot block)

Design polish:
- Header MegaPanel sub-link: gradient hover + white text + shadow on hover (was hover:bg-brand-50 only)
- Top-level mega menu: bigger padding + bold + bottom-bar hover indicator
- StatStrip: 8 narrow cards → 4 large cards (sm:grid-cols-4) with 12 size icon, 28px value, blur halo

Verify:
- scripts/verify-cross.mjs: parallel PHP (admin/clone1234) + React (testlogin/test1234) flow
- 50 iterations × 11 checks = 550/550 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 14:17:43 +09:00
chpark df72d3888a mypage tabs + admin items/sendcost/eyoom-menu + cert/charge mocks + theme cookie
mypage:
- /mypage/posts: posts authored across active boards (g5_write_*)
- /mypage/scrap: scraped list with subject lookup + delete action
- /mypage/respond: who liked/disliked the user's posts (g5_board_good x g5_write_*)
- /mypage/profile: editable email/hp/homepage/signature/profile + open/mailling/sms toggles

admin:
- /admin/shop/items: inline edit price/stock/use + create
- /admin/shop/sendcost: zip range shipping rules CRUD
- /admin/eyoom/menu: per-theme menu inline edit (g5_eyoom_menu)

mocks:
- /auth/cert: identity verification (g5_member_cert_history insert + member update)
- /wallet/charge: point top-up (mb_point + g5_point ledger), 5 PG presets

theme:
- /api/ui/theme picks {basic|eyoom|amina|youngcart} into slot_theme cookie
- root layout reads cookie, injects --theme-primary CSS var + data-theme attribute

Verify: 600/600 PASS over 50 iterations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:26:03 +09:00
chpark c231d652fb 14-game engine + /shop/buylist + visit counter + 4 admin write pages + theme tokens
Game engine: extended to 14 slot games (seastory/davinci/oceanparadise/
  cherrymaster/yamato/kyoushi/lupin/taiku/matsuri/marilyn/giatrus/rings/
  bakabon/slot) with per-game symbol weights and paytable

Pages:
- /shop/buylist: member order history (g5_shop_order)
- /admin/config/popups: g5_new_win create/delete with begin/end times
- /admin/boards/faq: g5_faq_master CRUD
- /admin/boards/contents: g5_content static page editor
- /admin/shop/banners: g5_shop_banner CRUD

Visit counter:
- lib/visit-counter.ts noteVisit() with throttled g5_visit_sum upsert
- Layout fires fire-and-forget on every render
- maybeRun('compress_visit_log') purges 90d+ entries

Themes:
- amina: sky-blue minimalist tokens
- youngcart: warm orange commerce tokens

Mypage: 구매내역 link now points to /shop/buylist (was /shop/orderinquiry)

Verify: 600/600 PASS over 50 iterations after deploy

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:08:06 +09:00
chpark d175f46a09 shop checkout flow + 3-game spin engine + admin board edit + lightweight cron
Shop: /shop/[itemId], /shop/cart with checkout, /shop/order/[odId]
Games: 3-game engine (fortunes, fivetreasures, bacara), /games/[game]/play
Admin: /admin/boards inline rename + actions
Cron: PG-row-lock cron helper (no Redis needed)
Verify: 600/600 PASS over 50 iterations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:19:28 +09:00
chpark 04bb3e617f V3 home: TopWinners + HotBoardsCarousel; shop list; admin point/level/block
Home additions:
- TopWinners: top 5 point holders with tiered medal cards
- HotBoardsCarousel: horizontally scrollable boards (free/review/mukti/humor/pick/lottery_ticket/guarantee/notice)
- StatStrip wired to live g5_visit_sum / g5_member / g5_board / g5_point
- Sidebar visitors now reads g5_visit_sum (today/yesterday/max/total)

New page:
- /shop — youngcart point mall list with category tabs + pagination

Admin write actions:
- /admin/members: server actions adjustMemberPoint (logs to g5_point), changeMemberLevel, toggleMemberBlock
- Inline forms per row replace the prior read-only table

Verify: 500/500 PASS over 50 iterations (login/comment/good/scrap/logout)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 02:53:21 +09:00
chpark 59001dbc5f Add 201 React deploy + admin catch-all + redesign + tests
Stack on 201: PG 17 + Next.js 15 (Docker) + nginx (/, /php-ref/)
Home: StatStrip (8 metrics), LiveActivity feed, refined Hero aurora
Admin: 80+ menu catch-all renderer + read-only legacy table queries
Auth/CRUD: fix narrowing in 6 action routes, fix wr_last varchar(19),
  fix back() new URL on missing referer
Verify: 50/50 PASS across 5 iterations of login + comment + good + scrap

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 02:44:18 +09:00
chpark ca965fec90 Wire menu URL rewrites + add /games hub + end-to-end verification (85/85)
## Menu rewrites against the production /bbs/*.php URLs
The g5_eyoom_menu rows store legacy PHP URLs verbatim (/bbs/tv.php,
/bbs/point_guide.php, /bbs/exchange-amount.php, /bbs/Bighandbro.php,
/bbs/event_exchange.php, /bbs/slotlife.php, /shop/list.php,
/shop/orderinquiry.php, /roulette/?idx=1, /plugin/swiunApi/game.php?gt=mix
…). Added rewriters that map every one of those to the new app routes so
clicking any menu item lands on a real page.

## /games hub page
The 포인트게임 top-level link used to 404 (it pointed to /games which
didn't exist as a page). Built a proper hub: gradient hero, 15-tile
slot simulator grid (each with a unique color gradient + emoji), and
two callout cards for sports/mini-game branches.

## /tv/bighand
큰손형 방송 dedicated page with KICK CTA + schedule.

## Header polish
- whitespace-nowrap on every menu label so 보증사이트 / 먹튀사이트 /
  슬생TV no longer wrap at narrow widths.
- MegaPanel renderer that turns 3rd-level eyoom menu groups (스포츠 /
  미니게임 / 슬롯·릴) into multi-column section blocks instead of
  collapsing to an empty dropdown.
- Replaced 구매내역 link with /mypage so utility-bar 404 disappears.

## verify-everything.mjs
New end-to-end script that:
- Crawls every menu link (64 unique URLs) and asserts non-404.
- Real interaction tests: testlogin login → board list → post view →
  comment POST → recommend POST → admin login → admin dashboard render
  check → admin theme picker visible (4 themes) → theme switch POST →
  logout POST → attendance check POST.

Result: PASS 85 / FAIL 0 / TOTAL 85. Report at next-app/verify-out/.
2026-04-27 20:54:51 +09:00
chpark 50f1d5cfb6 Pull mega-menu from g5_eyoom_menu and redesign home with Tailwind v4
## Menu now matches production exactly
- Read the 122-row inspection2.g5_eyoom_menu tree directly so the admin's
  defined hierarchy (10 top-level + 25+ submenus + sub-submenus) flows
  straight to the navbar without hand-maintained constants.
- Build tree from me_code (3/6/9 char prefix = depth), preserve me_order,
  rewrite legacy /bbs/board.php?bo_table=foo + /bbs/qalist.php +
  game/exchange/lottery URLs into the new app routes.
- Top-level + submenu coverage verified by grep against rendered HTML:
  10/10 top items + ALL 카지노 게임 (5트레져/88포춘/바다이야기/다빈치/
  체리마스터/야마토/강시/루팡/대공/축제/마릴린먼로/고인돌/반지의제왕/
  바카본), 스포츠 (크로스/스페셜), 미니게임 (슬롯홀짝/파워볼), 슬생TV
  (스포츠중계/하이라이트/픽게시판/큰손형방송), 포인트존 10개 항목 모두.

## Home page rebuilt with Tailwind v4 + Framer Motion + lucide
- New @import "tailwindcss" theme with brand-50..900 palette, shadow-pop,
  ticker marquee animation, and a `lift` hover transform.
- Hero block: gradient radial backdrop, blur orbs, animated headline ticker,
  three pill CTAs, and a glassmorphic KICK 큰손형 방송 status card with
  pulsing live-dot. Status pulled from getKickStatus() (live/break/offline
  by hour & weekday).
- 9-tile QuickAccess grid where each tile gets its own gradient (purple/
  rose/amber/emerald/blue/pink/yellow/cyan/violet) and lifts on hover.
- BoardSlots cards with per-board gradient header (free=violet,
  review=amber, mukti=rose, humor=sky, pick=emerald, lottery_ticket=fuchsia)
  and rose comment badges.
- Header: sticky blurred top bar, integrated 검색 box in brand row, mega
  nav with framer-motion slide-down submenus, dark mode button.
- Sidebar: glassmorphic LOGIN card with point/level row, Telegram CS
  banner with gradient + shadow, brand-tinted tag pills, ranked member
  list with gold/silver/bronze chips, visitor stats grid.
- Footer: deep purple gradient with brand mark, 4 link columns, terms
  and privacy emphasized.

## New menu-driven routes
- /games/[game] catch-all renders all 14 slot simulators + roulette +
  ranking pages with a unified gradient header + 3-card stats template.
- /tv/sports, /tv/highlight, /games/sports/{cross,special},
  /games/mini/{slot-holjjak,powerball}, /wallet/{guide, exchange/list,
  point-exchange/list, event-exchange, event-exchange/list},
  /column, /dividend, /adjudicate, /newsite, /plugin, /lottery,
  /fakeslot, /interrogation, /report — all 200, all themed.

## Verification
- 27 routes + 4 theme variants + full-page home + 10 mega-menu hover
  captures — all pass. PNGs under next-app/screenshots/.
2026-04-27 20:38:47 +09:00
chpark 30e9b7a8ee Build out the user-facing site to match production scope
After the initial scaffold the site was missing most of the production
surface (회원가입/마이페이지/메가메뉴 카테고리/관리자/게임/포인트존/...).
This commit closes that gap and verifies every route end-to-end with
playwright screenshots (27/27 pass).

## Theme system
- Replaced eyoom theme with a higher-fidelity reproduction of the
  production eb4_maga_005 layout: top utility bar (북마크/회원가입/구매내역
  /추가메뉴), brand row with 로그인/내글반응/쪽지 icon stack with badges,
  purple gradient mega-menu carrying 10 categories with submenus, dark
  mode toggle, sticky LOGIN box + 텔레그램CS box + 태그 클라우드 + 회원
  랭킹 + 방문자 stats in the sidebar, and a footer with 이용약관/개인정보
  처리방침/이메일무단수집거부.
- Added IndexHome slot to the theme contract; basic/amina/youngcart got
  matching implementations so theme switching keeps working.
- Layout now consistently provides the right-rail sidebar on public pages
  and hides it on /login, /register, /mypage and /admin (admin uses its
  own left rail).

## Pages added
- Auth: /register (with API-backed insert into the new members table),
  /auth/recover (id+password recovery shells).
- /mypage dashboard with 12 sub-routes.
- /memo, /bookmarks, /new, /tags, /tag/[tag], /profile/[nick].
- 10 mega-menu landing pages: /guarantee, /guarantee/apply, /mukti,
  /complaint, /inspection, /fakesite, /event, /lottery_ticket,
  /gift_coupons, /gift_exchanges, /notice; /games (bacara, fortunes,
  fivetreasures, slot, roulette, ranking); /wallet (+ exchange,
  point-exchange, slotbuff); /tv; /guide (+ community/pointgame/mukti/tv);
  /help/qa, /help/faq.
- Static pages: /page/provision, /page/privacy, /page/noemail,
  /page/aboutus, /page/manual, /page/attendance.
- Per-board: /[slug]/write, /[slug]/[wrId]/edit, /[slug]/search.

## Post interactions (wired against legacy g5_* tables)
- POST /api/posts/create        — insert into inspection2.g5_write_<slug>
- POST /api/posts/[id]/comment  — insert is_comment row + bump wr_comment
- POST /api/posts/[id]/good|bad — bump wr_good/wr_nogood + g5_board_good
- POST /api/posts/[id]/scrap    — insert g5_scrap
- POST /api/posts/[id]/report   — write into writing_activity
- POST /api/posts/[id]/delete   — owner+admin gate, soft-delete row
- POST /api/ui/dark-mode        — flip slot_dark cookie

## Admin
- /admin layout with left nav (10 sections) gated by member level >= 10.
- /admin                — dashboard with live counts pulled from PG
- /admin/members        — searchable member list with status badges
- /admin/boards         — board roster with post/comment counts
- /admin/betting        — bacara/swiun/game-point counters + recent feed
- /admin/stats          — 14-day visit chart + top boards + level histogram
- /admin/themes         — 4-theme picker (already existed, now polished)
- /admin/{menu,permissions,points,games} — stubs for M5

## Infra fixes
- Postgres pool hoisted onto globalThis so HMR doesn't leak connections
  ("sorry, too many clients already" 500s).
- Removed broken Next.js redirects() entry that prevented dev from booting.

## Verification
- scripts/screenshot.mjs: pre-logs-in as admin/test1234, then captures 27
  pages + 4 theme variants of /. All 200, all rendered. PNGs committed
  under next-app/screenshots/ for review.
2026-04-27 20:20:49 +09:00
chpark 980d7d905d Add Next.js + PostgreSQL rewrite scaffold with 4-theme system
Stack
- Next.js 15 (App Router) + TypeScript + Drizzle ORM + postgres-js
- Node scrypt for password hashing; PBKDF2 verifier for legacy gnuboard5 hashes
- pnpm workspace monorepo: apps/web + packages/{db,auth,themes,...}

Themes (admin-selectable at /admin/themes)
- basic     : 그누보드 default reproduction (light, blue accent)
- eyoom     : eb4_maga_005 매거진 reproduction (dark, orange accent, ranking sidebar)
- amina     : Aminam Builder reproduction (light, violet gradient, card grid)
- youngcart : 영카트 shop reproduction (red accent, search bar, category nav)

DB
- New schema (12 tables) pushed to PG via drizzle-kit: members, sessions, boards,
  posts, point_ledger, app_settings, bacara_*, lottery_tickets, roulette_spins,
  game_points, board_groups
- Legacy data still readable from inspection2 schema via @slot/db/legacy

Verified end-to-end against the migrated DB on localhost:3000:
- Home renders with active theme tokens injected as CSS variables
- /free lists 442K real posts from inspection2.g5_write_free
- Login (testlogin/test1234) issues session cookie, header switches to
  "테스트님 환영합니다 / 로그아웃"
- Switching app_settings.theme.global from eyoom → amina swaps colors,
  layout, and Korean nav labels site-wide on next request

Migration docs added: 03-migration-plan, 04-theme-architecture,
05-local-dev-setup, 06-feature-inventory.
2026-04-27 18:51:32 +09:00
chpark 0e549cad46 Initial import of slot-ss.com (gnuboard5 + Eyoom + YoungCart) for migration
Original PHP source rsync'd from production server (slot-ss.com) on 2026-04-27.
Excluded from import:
  - data/editor (74GB user uploads), data/file (8.5GB attachments)
  - data/member_image, vendor/, db100up/, caches/sessions/logs/tmp

Includes:
  - 11,636 files, ~206MB source code (gnuboard5 v5.6.6, Eyoom builder, YoungCart 4)
  - 28 plugins (bacara, chatbot, cron, swiunApi, sns, sms5, ...)
  - Active theme: eb4_maga_005 (Eyoom magazine layout)
  - Local Docker dev stack (PHP 7.4 + Apache + Redis + MariaDB) under docker/
  - PostgreSQL migration setup (pgloader configs) under db/
  - Architecture/migration docs under docs/

Single non-source patch: src/config.php now reads G5_DOMAIN_OVERRIDE env var
so the local Docker stack can serve at http://localhost:8088 without touching
the production constant. Falls back to https://slot-ss.com when unset.
2026-04-27 18:23:16 +09:00