← Back to Resume
Download

Career Description — Hyeonjun Kil

GameDuo

2025.01 — Present

Mobile game development and publishing company. Shared backend platform design for 6 live game environments (12 operating branches), data pipeline engineering, and common package system operations

DEV Team Platform Part Leader

2026.04 — Present

  • •Single-shard chat bottleneck at 6,000 msg/s: ack p95 767ms, 99.39% acceptance. Personally led sharding and load validation. Separately set shared done criteria and verification templates for the 3-person BE/FE/AI part, tracking work in quarterly OKRs with capacity targets (6,000 CCU, 18,000 RPS, 90,000 RPS burst). Load-test ack p95 767ms→6.6ms, scaling 1→4 shards.
  • •Archive backfill saturated RDS CPU at 99.8%, throughput 9.3 items/min. Performance Insights isolated a query causing 99.5% of load; replaced N+1, DATE() predicates that prevented index use, and full-column reads with IN() batching, direct date comparison, and selected columns. Backfill throughput up 26x (9.3→247 items/min), Lambda p50 63.2s→1.36s, 15,333 completed with 0 pending.
  • •Company-wide AI agents needed centralized per-user policies, device identity, and usage tracking. Owned design, operations, and merge approval for device registration, policy, remote-control, and usage tooling; AI agents implemented it before operational handover. Assigned the usage-reporting switch to 92 people on the active roster; all 87 reporting online devices applied it, and 525 automated security tests passed.
  • •Coding standards, domain knowledge, and verification rules were scattered across individual setups. Unified rules, agents, hooks, and domain knowledge in Git with local RAG search. Every member shares the same AI working context via git pull, with pre-review criteria captured in an automated checklist.

DEV Team Server Developer

2025.01 — 2026.03

  • •High DB and CPU load during metrics sync. Evaluated partitioning: write IOPS fell, but read IOPS rose and CPU load persisted. Chose lower Lambda concurrency over a structural change with little benefit for its code complexity.
  • •Batch processing collection limits (60 days). Replaced batch runs with EDA on-demand processing to distribute peak load. Expanded metrics range 6x (60→360 days), processing time 2h→5min.
  • •Code duplication and convention inconsistency across 7 projects. Introduced shared NestJS packages and auto-deploy (10 utility modules + Game Server Kit). Upgrade rollout across 7 projects 3hrs→15min via automation, with shared-code changes consolidated into one package.
  • •Slow marketing queries across Google Ads/Meta/TikTok data. Normalized read path + index tuning to avoid full-scan on 100-column table. Performance improved 97% (18s→0.5s).
  • •Regulatory risk from game probability disclosure requirements. Integrated a DynamicModule probability package across games and built a CDK audit-log pipeline. Achieved 94%+ integration test coverage (12 suites, 115 tests).

Projects

Real-Time Game Chat Server (Multi-Tenant)

2026.04 ~ Present

Designed a multi-tenant real-time chat server to be shared across games, sizing a 6,000 CCU / 18,000 RPS target and validating it up to 20,002 CCU held for 900s in a dev load test

  • •No capacity model for chat infrastructure shared across games, blocking server sizing and SLO targets — Based the capacity model on commercial chat solutions' published rate-limit/PCU specs instead of internal guesswork, defining a sizing formula for a single multi-tenant server frame, Adopted 6,000 CCU / 18,000 RPS / 90,000 RPS burst targets into quarterly OKRs; a dev load test held 20,002 CCU for 900s
  • •Redis Streams WAL hit a single-threaded write bottleneck at 6K msg/s (EngineCPU 99.9%, ack p95 767ms) — Distributed the WAL stream across a 4-shard cluster and compacted entries into native fields (removing Lua serialization) — chose horizontal sharding over vertical scaling, since single-threaded Redis serializes writes and cannot scale them vertically, ack p95 767ms→6.6ms (~116x), WAL backlog 80,000→2,838 cleared, 99.99% accept rate at scale
  • •Messages were 100% rejected under concurrent multi-tenant load due to a missing scope key — Built a 5-tenant concurrent load-test environment and removed rejects via hot-path log removal and message scope keys, Achieved ack p95 42ms (target <100ms) and 0.04% error rate (target <0.1%) at 299K messages sustained over 5 minutes
  • •The outbox Lambda stalled at 2 concurrent executions (2% of reserved 100) with IteratorAge flat at 11 minutes despite zero throttles — Instead of batching tweaks, traced the cause to a tenant#date partition key that sent a day of writes to one partition, and spread writes across 10 partitions with a 0–9 shard suffix, In a sandbox load run, IteratorAge 658s→35s (−95%) and Lambda concurrency 2→8
  • •After hot-channel fanout migration, the bottleneck was not isolated between Redis server Lua, gateway event loop, a single command queue, and topology — Added attribution instrumentation before changing architecture, then validated Valkey serverless SSUBSCRIBE, per-channel subscriptions, and logicalChannelId-sticky connection pools step by step, Passed sandbox validation; a standalone measurement with connection pool size 4 reduced the command queue from 5,940 to 716 and processed 878,205 messages with zero loss
  • •Offline DMs, unread counts, joined-room lists, and group fanout lacked durable per-user state, risking mixed ownership between chat and game domains — Converged requirements onto a per-user room index, keeping the chat server responsible only for mechanics/characterId while game servers owned profile hydration and group-domain actions, Completed server-side DM, unread-count, joined-room, and group-fanout capabilities under one index model, with server/sandbox QA completed before Unity handoff
  • •Gateway tasks were repeatedly OOM-killed after performance changes, while outbound queues, observability retention, and heap caps remained competing root-cause hypotheses — Pre-registered and rejected the egress-budget hypothesis, then isolated retained-heap growth and heap-cap alignment through heap snapshots, diagnostic logs, and A/B measurements, Observed zero OOM events in post-fix validation and zero configuration drift in the targeted infrastructure rollback plan

Tech Rationale

Adopted a Redis Streams Consumer Group-based WAL (Write-Ahead Log) for message ordering, and distributed it across a 4-shard Valkey cluster instead of vertical scaling — a single-threaded Redis cannot resolve write bottlenecks by adding cores. ECS Fargate ARM64 migration was adopted only after validating resource efficiency under identical load.

TypeScriptNestJSRedis StreamsValkey (Cluster)Valkey ServerlessDynamoDBAWS ECS FargateARM64 (Graviton)NLBTerraformk6Grafana

Marketing Integrated Platform

2025.02 ~ Present

Unified marketing platform managing Google Ads/Meta/TikTok campaigns, creatives, and metrics in a single system, built on dedicated marketing DB separation

  • •Large marketing-metrics archive backfill stalled at 63s Lambda runtime and 99.8% RDS CPU, ETA 15 hours — Diagnosed the root cause as N+1 queries and a non-SARGable DATE() predicate (index miss) and removed both — chose a single 30-day batch fetch with in-memory latest-version dedup over per-row reads that were saturating RDS, Improved throughput 26x (9.3→247/min), Lambda runtime 63s→1.36s
  • •MKT Sheet BigQuery reads — Migrated to the Storage Read API, Migration completed
  • •Slow marketing queries on a 100+ column denormalized table — Normalized table into main/time-series/prediction, tuned indexes + cursor pagination, Performance improved 97% (18s→0.5s)
  • •Meta asset sync performance bottleneck — Replaced per-row ORM saves — which incurred heavy transaction overhead — with bulk INSERT and batch deletes, Image sync reduced 72% (25.7s→7.1s), DB transactions reduced 95% (10~16s→0.3~0.5s)
  • •TikTok deployments created orphan campaign/adgroup/ad resources when an external API partially succeeded before internal persistence, or retries were blocked by deployment guards — Unified idempotency per deployment path: Smart+ V2 level-by-level get-or-create with immediate persistence, v1 campaign-level reuse, and regular ad-level flags, Passed 31 unit tests for partial-failure retries and applied a policy to prevent recurrence of 2 orphan campaigns and 2 orphan ad groups
  • •A 26.37M-row / 27GB audit-log table lacked an index for parent-based lookups, causing page queries to trigger large full scans and prolonged IO saturation — Declared the index at the entity layer to prevent drift, pre-created the online DDL during a low-load window, and hardened the migration with duplicate-index no-op handling plus real DDL integration tests, Eliminated full-scan queries that had run for up to 36 minutes and reduced EXPLAIN-estimated scans to 3 rows, resolving the audit-log lookup incident
  • •Lambda handler build waits and quarantined test suites delayed marketing-platform CI feedback and left gaps in regression checks — Sharded handler builds, checked for missing expected artifacts, and restored quarantined suites with validation through FULL 8-shard CI, Reduced build wall time from 1,041 to 451 seconds in a manually triggered 1-vs-6-shard workflow experiment with 58 expected handlers and 0 missing; aggregate build work increased from 1,006 to 1,801 seconds. Separately restored all 83 quarantined suites and passed FULL CI
  • •Missing links between Meta ads and local assets left 2,235 ads with unlinked assets under the same UI filter — Backfilled asset links across 15 Meta accounts and 292 campaigns, comparing before and after under identical UI filters, Ads with unlinked assets 2,235→430: 1,805 fewer (80.8%); the remaining 430 had no asset matching the local ad ID in the current Meta response

Tech Rationale

For metrics-sync DB load, chose lower Lambda concurrency over partitioning: write IOPS fell, but read IOPS rose and CPU load persisted, offering little benefit for the added code complexity. Designed a hybrid GCP Pub/Sub → AWS Lambda/SQS pipeline for event-driven processing with the Outbox pattern for non-blocking async event publishing.

AWS LambdaApache ArrowBigQueryGCP Pub/SubGoogle Ads APIMeta APIMySQLNestJSS3SQSBigQuery (Storage Read API)TikTok APITypeORMTypeScriptgRPCTikTok Smart+IdempotencyOrvalZod

Internal Common Library System

2025.07 ~ Present

Development and operation of NestJS utility (10 modules) + Game Server Kit (2 packages) for multi-project code consistency

  • •CI TEST job averaged 15m47s, delaying feedback — Chose tsc-native ts-jest isolatedModules with explicit Entity types over @swc/jest, which had weaker decorator-metadata compatibility, Cut average CI TEST job time 61% (15m47s→6m06s); passed 81 suites/978 tests
  • •Game-server shared code split across 5 branches + one game's 17 game-data definition modules were 2+ years diverged from the published package — Extracted the game-data definition modules + 5 submodules into a standalone package, then migrated 610 files / 310+ imports in one game, and later audited hardcoded names, moved them to config injection, and added a regression guard, Game-data module updates now ship as a single npm version bump (manual migration of 610 files → 0); a live 500 caused by the migration was hotfixed 82 minutes after report
  • •Each app injected its own static-data LRU cache, so boot-time data warming on live game servers took minutes — Moved static-data storage into the shared kit, removed per-app LRU injection, and added negative caching and preloadAll, Live game-server boot warming 138.1–199.5s → 25.8–37.8s, then 0.82–1.08s after switching the app warmer to preloadAll
  • •Manual library upgrades taking 3 hours across 7 projects — Added workflow_dispatch+matrix and changed-package CI tests on GitHub Packages, Reduced 7-project upgrade runtime 3h→15min
  • •Common code duplication across services increasing maintenance cost — Designed 10-module library system: core, repository, cache, lock, slack, crypto, smb, hash, type, iac, Unified shared code across 7 projects with standardized dependency management
  • •Repository layer had grown beyond 2000 lines and lacked type safety — Replaced read-then-write duplicate-key races with atomic upsert and automatic audit-log branching; narrowed types with overloads/generics and split the Repository into purpose-specific modules per SRP, Refactored 2000+ lines into shared Repository abstraction layer eliminating CRUD duplication
  • •Game-server cache logic was duplicated per project, increasing consistency and maintenance burden — Combined local LRU and distributed cache in a decorator-based hybrid AOP library to reduce network round-trips without the cross-instance inconsistency of local-only caching; separated tag indexing and single-flight per SRP, Released cache library v0.5.0 — 262 tests across 28 suites passing

Tech Rationale

Implemented ElastiCache (Redis) distributed lock as AOP decorator to separate lock logic from business code. Evaluated 5 options for Jest 30 VM isolation and adopted poolSize=2.

ElastiCache (Redis)GitHub NPMNestJSSlack APITypeORMTypeScript

CS Support Chat Server

2026.04 ~ Present

Fully isolated the customer-support (CS) chat server onto ECS from a shared deployment, and validated authentication, security, and load ceilings

  • •CS chat was coupled to a shared deployment, causing resource contention and deployment coupling — Fully isolated the service onto ECS Fargate and automated deployment via Terraform IaC (S3 state), GitHub Actions OIDC, and an observability sidecar — adopted a centralized game-token verification path over per-game distributed checks, Completed independent service cutover with modularized Terraform, an 11-panel Grafana dashboard, and 8 alerts
  • •Layer coupling and ad-hoc token lifetimes in the new CS chat domain posed security and maintenance risks — Separated responsibilities into a 4-layer Clean Architecture and introduced OAuth2 access (5min)/refresh (1h) tokens with ETag/304 polling — sending only deltas instead of full payloads per poll, Passed 39 tests across 12 suites; applied IaC plan (+10 resources) with zero incidents
  • •1.0 vCPU ceiling, 40~90s cold start, and bloated images blocked spike-traffic handling — Redesigned task resources and ALB RPS autoscaling, and cut cold start via native ARM64 builds and Dockerfile slimming with migration separation, Reduced image 381→254MB (-127MB) / build 5→2min / cold start by 30%; 0% failure on a k6 500-VU spike
  • •No cross-project data isolation, request rate limiting, or attachment access control — Introduced cross-project isolation (triple-validation helper), Redis-backed rate limiting (auth 5/min, refresh 10/min, message 30/min), and an attachment FK integrity migration — rejected in-memory throttling for its multi-instance bypass risk, Merged the security integration with zero type errors and established cross-org/project isolation specs
  • •Multiple inquiries were mixed inside one CS chat room, making per-inquiry counts and handling-time metrics difficult, while video attachments for bug reports were unsupported — Designed additive APIs for immutable message-reply links, user-level chat lists, and a dedicated video-upload path with MIME, size, TTL, and daily limits, Established message-level reply/target changes, user-level lists, video inquiry playback, and inquiry-count/handling-time aggregation (20MB, 10 uploads/day, 15min TTL)

Tech Rationale

Isolated the service onto ECS (Terraform IaC + GitHub Actions OIDC) to break resource contention and deployment coupling, and adopted a centralized game-token verification path over per-game distributed checks. Rate limiting was implemented with a Redis-backed throttler for multi-instance consistency.

TypeScriptNestJSTypeORMOAuth2AWS ECS FargateARM64 (Graviton)TerraformGitHub Actions OIDCRedisk6GrafanaPresigned URLRedis Rate Limit

AWS Lambda Migration & Event-Driven Architecture

2025.06 ~ 2025.08

Resolved batch job limitations from marketing metrics 60-day → 360-day expansion and serverless transition for batch processing

  • •Full serverless migration risked operational stability — Designed hybrid architecture keeping API server on EC2 while separating batch/job processing to Lambda, Preserved API availability with zero impact, isolating only batch workloads to contain operational risk
  • •Batch processing limited to 60-day collection range with 2-hour runtime — Established Event-Driven flow with SQS+Lambda+EventBridge, Reduced batch time 2h→5min, expanded collection 6x (60→360 days)
  • •Data consistency risk during event publishing — Adopted Transactional Outbox Pattern for scheduled and delayed event publishing, Kept data consistent across distributed event processing
  • •After cache disk-full recovery in the CDK deploy workflow, Lambda handler webpack builds reproduced V8 OOM, combining slower deployments with no regression guard — Separated runtime-transform dependencies into generated artifacts, raised the default handler batch, and retried only failed batches through an adaptive 8→4→2→1 split sequence, Removed the Lambda handler build-OOM root cause, added CI regression guardrails, and validated the deployment path through 3 passing CI runs
  • •DB connection exhaustion during massive Lambda execution — Introduced RDS Proxy connection pooling, Resolved connection exhaustion and stabilized database access

Tech Rationale

Chose Lambda to decouple batch/event workloads bound to the monolith server, enabling independent deployment. Adopted SQS for async processing to resolve scaling limitations under traffic fluctuation.

TypeScriptNestJSAWS LambdaSQSSNSEventBridgeRDS ProxyAWS CDK

In-Game Multi-Language Translation System

2026.02 ~ Present

Redesigned the in-game notification translation domain model — decoupling AI translation from library-based conversion into a 3-stage pipeline

  • •Simplified Chinese was modeled inside the AI translation settings domain despite not being AI-supported, and settings storage/retrieval depended on the Traditional Chinese AI translation state — making independent toggling impossible without a breaking change — Extracted the derived-conversion module from the AI translation module into 9 use cases with dedicated entity/repository/scheduler, and applied the global-inheritance pattern for effective settings, Clarified domain boundaries by extracting 9 use cases and enabled independent toggling of derived conversion rules
  • •Decoupling required a breaking API change — Simultaneously deployed FE/BE/Gateway with role permission migration for zero-downtime transition, Completed the breaking API change without incident and cut effective-settings DB queries by 50% (4→2)
  • •The detect cron lacked version priority, delaying translation of the latest version; 30-second interval further slowed response — Added version ID-based priority ordering to detect SQL, shortened the processing interval from 30s to 10s, and raised batch limit from 100 to 200, Eliminated latest-version translation lag; progress UI plus total-count caching improved user visibility
  • •In sandbox, the detect scheduler queried all 159 versions at once (full scan of a 3.27M-row table on live), saturating Read IOPS at 190–470/s and locking some users out for 60s — Ported the per-version loop from the AI detect module, added distributed-lock timeout/recovery, and replaced the NOT EXISTS full scan with an indexed staged lookup, Split into per-version queries (39ms for one version on Live EXPLAIN) and bounded each run with pagination and a per-run cap
  • •The AI translation scheduler stalled on Vertex AI 429 quota errors, leaving 83,796 requests unprocessed on live — Traced the retry path: in-batch and recovery retries compounded to 9 effective attempts, and 13 scheduler instances retried with no backoff or jitter, Identified both causes (a retroactive backfill of 160 versions × 4 languages and a 13-instance retry storm), deleted the 83,796 stuck requests, and split out 4 follow-up tasks

Tech Rationale

Materialized the responsibility boundary between AI translation and library-based derived conversion inside the code structure. Split the Detection → Processing (AI) → Conversion (library) pipeline into independent modules and secured concurrent request integrity with a 2-stage race guard plus pessimistic write lock

TypeScriptNestJSTypeORMMySQLopencc

Marketing Platform Audit Log System

2025.01 ~ 2025.04

Resolved delayed balance issue response caused by inability to track data change history during game operations

  • •Inability to track data change history across environments and projects — Designed Git-like version control system with UUID-based cross-environment/project entity tracking, Kept data consistent across 6 games
  • •Manual entity change recording prone to omission — Applied Event Sourcing-based change tracking with Auditable decorator + TypeORM Subscriber pattern, Automated entity change tracking with consistent logging across all game environments
  • •Multi-environment version conflicts during data merge — Developed 3-Way Merge Engine with parent/child entity conflict detection and unique constraint handling, Automated version merging across 6 games' environments
  • •Expensive full-snapshot comparison for every version diff — Designed Version Diff Engine with dual strategy: incremental comparison and snapshot comparison based on Base Audit availability, Dual-strategy version comparison (incremental + snapshot) for performance optimization
  • •Entity tracking failures due to PK dependency during migration and merge — Introduced shared identifier-based entity tracking decoupled from PK dependency, Tracked entities accurately through migration, comparison, and merge

Tech Rationale

Adopted TypeORM EntitySubscriberInterface after dedicated analysis of subscriber behavior and constraints. Designed AOP-based approach combining Auditable decorator + Subscriber to automatically collect entity changes into a standardized audit pipeline.

TypeScriptNestJSTypeORMMySQL

Cloud Data Sync System

2025.08 ~ Present

Built S3-based sync and automated DDL management system to resolve dynamic game data inconsistency across environments

  • •Dynamic game data inconsistency across environments — Built S3-based cross-environment data synchronization across development/staging/production, Unified game data state across all environments
  • •Manual DDL schema management causing sync failures — Created automated DDL management engine with dynamic PK column type resolution, column type mismatch detection with MODIFY, and automatic index creation/RENAME, Automated database schema drift detection and reconciliation
  • •Large-scale Cloud Data ingestion and S3 upload bottlenecks — Analyzed and optimized ingestion and upload pipeline, TRUNCATE→DELETE optimization for batch operations — 77% latency reduction (57.5s→12.9s)
  • •Sync job instability causing operational issues — Implemented job separation, transitioned scheduling approach, tuned timeouts, and introduced non-blocking processing, Data layer resilience through schema optimization and safe migration strategies
  • •Four data-sync service bugs: Redis cache invalidation, DDL-SKIP metadata, copy-key deletion, and data-protection option propagation — Diagnosed and fixed all four issues systematically, Diagnosed and fixed 4 critical bugs to stabilize data-sync operations
  • •Risk of unintended full data deletion when a protection option was not forwarded on some migration paths — Forwarded the data-protection option across the four POST migration paths that were missing it, Blocked unintended full data deletion risk

Tech Rationale

Applied S3 Lifecycle policies (30d Glacier IR, 90d expiry) for cost optimization. Switched from event-triggered to scheduled execution to reduce sync miss risk.

TypeScriptNestJSTypeORMMySQLS3

Probability Calculation & Audit Log Analytics Pipeline

2026.02 ~ Present

Built probability calculation package and CDK-based audit log analytics infrastructure to address regulatory risk from lack of game probability verification

  • •No reusable probability calculation module across 6 live game environments (12 branches) — Packaged NestJS DynamicModule with 5 probability functions + Kinesis logging as shared probability package, Integrated the probability package across 6 live game environments (12 branches), cherry-picking main plus 11 branches
  • •No audit log analytics infrastructure for probability verification — Codified CDK analytics pipeline: Kinesis→Firehose (Dynamic Partitioning+Parquet)→S3→Glue→Athena, Integrated the probability-disclosure audit-log pipeline across 6 live game environments (12 branches)
  • •Mock-based tests lacking regression confidence for infrastructure code — Replaced mocks with LocalStack + Testcontainers integration tests, Secured 94%+ coverage (12 suites/115 tests)

Tech Rationale

Codified Kinesis → Firehose (Dynamic Partitioning + Parquet) → S3 → Glue → Athena pipeline with CDK. Chose Parquet columnar format for Athena SQL cost optimization. Replaced mock-based tests with LocalStack Testcontainers for integration testing.

Contribution: Restructured initial implementation into a package. Independently handled P0 bug fixes, test stabilization (94%+ coverage), CDK infrastructure, and deployment across 6 live game environments (12 branches).

TypeScriptNestJSAWS CDKKinesisFirehoseS3AthenaGlueParquetLocalStackTestcontainers

Marketing Data Archiving & Custom Dashboard

2026.04 ~ Present

Built daily-snapshot archiving of marketing metrics (with immutability), a 4K-row custom dashboard, and alert observability

  • •Displaying 4K-row marketing metrics in one dashboard caused scroll lag and cell-sync bugs — Split BE (Raw SQL DISTINCT JOIN avoiding ORM hydration + in-memory cache) and FE (visible-row lazy fetch + 200-row chunks balancing network round-trips and render latency + per-pair caching) — rejected full loading due to response size and render cost, Displayed 3,341 of 4,458 rows mapped, stabilized response at 573ms cold / 221ms warm
  • •Sync paths used the latest snapshot instead of the reference-date cutoff, violating archive immutability (data contamination) — Redesigned the usecase/repository to honor cutoff semantics, made the stale-writer guard transactional, and introduced tombstone states for sync, Rebuilt 15,333 live archives (zero contamination), validated 287,020 archive-date records
  • •A transient log-query stack (Loki) outage fired 16 marketing alerts at once, flooding ops channels — After diagnosing the root cause, migrated all 16 alerts to a single analytics DB (ClickHouse) query, rewrote them via the dashboard API, and set a legacy log-stack decommission policy, Migrated 16/16 alerts (25 min), preventing alert-flood recurrence during log-stack outages

Tech Rationale

Archives must be immutable snapshots keyed by a reference-date cutoff rather than read-time state, so integrity was enforced with a stale-writer guard and tombstone states. The large grid uses visible-range lazy fetch with chunk caching instead of full loading.

TypeScriptNestJSReactAWS LambdaBigQueryClickHouseGrafanaMySQL

Activities

Boosting Developer Productivity with Amazon Q DeveloperConference Talk2025.10

Games on AWS 2025 Customer Session

Shared a case study of a single engineer scaling data pipeline capacity 270x in 10 days, measured by hourly concurrent job throughput

JNPMedi

Dev2 Team Docs Squad Backend Engineer

2023.06 — 2024.08

Clinical trial data management solution startup with KRW 16B cumulative investment (MSA-based)

Highlights

  • •Intermittent automatic e-signature failures caused by database deadlocks. Reproduced foreign-key (FK) shared/exclusive-lock deadlocks using SQL and lock tables. Derived two remedies: transaction ordering and SELECT FOR UPDATE pre-acquisition.
  • •VDR project schedule delay under MVP launch pressure. Emergency sprint with 2 BE + 1 FE: Event-Driven PDF conversion + permission-based workflow. Launched the MVP in 3 weeks and ended synchronous large-PDF conversion timeouts.
  • •Missing delivery/bounce tracking left email failures visible only after the fact. Received SES Configuration Set events through SNS and logged results in Datadog. Built Slack alerts for delivery failures and shared the implementation through a tech blog and internal seminar.

Projects

Maven Docs Electronic Consent System

2023.07 ~ 2023.09

Resolved inefficiency in collecting participant consent and e-signature regulatory compliance using Cyan (in-house Node.js framework)

  • •Inefficient individual consent dispatch for clinical trial participants — Created batch dispatch system for participant group management and batch consent dispatch, Streamlined consent collection per clinical trial
  • •Opaque event flow from batch + S3 event-based processing — Migrated to EDA + Outbox pattern, Made the event flow visible and set up a local test environment

Tech Rationale

Adopted EDA + Outbox pattern to eliminate synchronous service coupling. Designed plugin architecture for extensible input methods (text, checkbox, signature).

Contribution: Designed EDA transition, implemented plugin architecture, built batch participant registration with Signer table migration. 2-person BE team.

TypeScriptExpress.jsCyanAurora Serverless v2Knex.js

Maven Docs System Reliability Improvement

2023.08 ~ 2023.12

Resolved critical notification failures due to database Deadlocks in clinical trial e-signature notifications

  • •Production database deadlocks intermittently failed automatic e-signature processing — Reproduced child-INSERT/parent-UPDATE lock ordering in SQL and confirmed it through INNODB lock tables, Identified the FK shared/exclusive-lock deadlock mechanism and derived transaction-ordering and SELECT FOR UPDATE remedies
  • •Synchronous notification processing causing cascading failures — Designed and implemented AWS SNS → SQS → Lambda Event-Driven pipeline, Decoupled notification delivery from main transaction flow

Tech Rationale

Identified deadlocks between shared locks acquired by foreign-key (FK) checks on child INSERTs and exclusive locks on parent UPDATEs. Derived transaction ordering and exclusive-lock pre-acquisition with SELECT FOR UPDATE as remedies.

Contribution: Independently reproduced and analyzed the deadlock and derived remedies. Reproduced the scenario with SQL in DBeaver and verified it via INNODB lock tables.

TypeScriptExpress.jsCyanSlate.jsSNSSQSLambdaReact

Maven Mailing System Enhancement

2023.12 ~ 2024.02

Resolved lack of delivery status tracking and data consistency issues in email system

  • •Missing delivery/bounce tracking left email failures visible only after the fact — Configured SES Configuration Set → SNS → event processing pipeline with Datadog logging + Slack real-time alerts, Established email monitoring with delivery-event logs and Slack alerts for failures

Tech Rationale

AWS SES cannot synchronously confirm delivery status due to its async nature. Added SNS event destination to SES Configuration Set for async delivery/bounce event subscription.

Contribution: Designed and implemented SES Configuration Set → SNS → event processing pipeline. Led tech blog publication and internal seminar presentation.

TypeScriptExpress.jsAWS SESNodemailer

Maven Auth System Enhancement

2024.01 ~ 2024.02

Resolved user inconvenience and system scalability limitations from 1:1 user-organization structure

  • •1:1 user-organization structure limiting multi-organization management — Expanded user-organization relationship from 1:1 to 1:N structure, Supported multiple organizations per user
  • •API migration risking service downtime — Ensured backward compatibility throughout migration process, Achieved zero-downtime API migration with service continuity

Tech Rationale

Redesigned account-organization from 1:1 to 1:N to support clinical trial researchers participating in multiple organizations simultaneously. Added post-login organization selection flow for context switching.

Contribution: Full-stack change: schema migration, auth flow modification, and batch update of downstream service (Docs/Billing/Mailing) account-organization reference logic.

TypeScriptExpress.jsCyanAurora Serverless v2

Maven TMF New Project Development (Frontend)

2023.06 ~ 2024.08

Frontend development for clinical Trial Master File (TMF) management system

  • •No systematic Trial Master File (TMF) management system — inefficient regulatory compliance and document tracking — Mobilized as an emergency developer in a 1 BE + 2 FE team; defined MVP scope and built document upload, classification, version control, and Audit Trail on the Admin/Dashboard, Delivered the TMF management frontend MVP in 3 months, establishing systematic management of clinical-trial essential documents

Tech Rationale

Defined MVP scope focusing on core features (document upload, classification, version control, audit trail) under 3-month delivery constraint.

Contribution: FE developer in 1 BE + 2 FE team. Implemented Admin/Dashboard document upload, classification, and audit trail features.

ReactTypeScriptJotai

Maven VDR MVP Development

2024.06 ~ 2024.07 (3 weeks)

Emergency deployment for delayed VDR project under MVP launch pressure

  • •Synchronous PDF conversion causing timeouts on large documents — Designed Event-Driven PDF conversion triggered by S3 upload → Lambda lightweight conversion → SNS/SQS notification, Eliminated synchronous timeouts; large documents now flow through async pipeline reliably
  • •No role-based document access control for medical workflows — Engineered permission-based workflow managing document access and approval by medical role, Defined per-role document access and approval workflow
  • •VDR project schedule delay under MVP launch pressure — Executed 3-week emergency sprint prioritizing core features, Delivered MVP within 3-week timeline (BE 2 + FE 1 team)

Tech Rationale

Designed EDA-based async conversion pipeline (S3 trigger → Lambda conversion → SNS/SQS notification) to structurally resolve synchronous PDF conversion timeout issues.

Contribution: 1 of 2 BE developers. Designed and implemented EDA document processing pipeline and large-scale async PDF conversion worker. Delivered MVP within 3-week emergency sprint.

TypeScriptLambdaS3SNSSQS

Maven Billing Subscription Management System

2023.06 ~ 2024.08

Subscription, plan, and license management system for all Maven services

  • •No support for organization-specific subscription plans — Shipped org-specific custom plan Internal API, Facilitated tailored subscription offerings per organization
  • •Non-renewable plans could be incorrectly renewed or re-subscribed — Added renewal/re-subscription blocking logic for non-renewable plans, Kept the subscription lifecycle consistent with business policy

Tech Rationale

Introduced event queue for async cleanup processing after subscription expiry. Enforced non-renewable plan re-subscription blocking via bundles.is_renewable schema attribute at the data level.

Contribution: Implemented org-specific custom plans, event queue-based inventory auto-deletion, and renewal eligibility logic. Multiple PRs directly contributed.

TypeScriptExpress.jsCyanAurora Serverless v2Knex.js

Activities

Email Delivery Monitoring through AWS SES Event LogsTech Blog2024.03

Published technical article on building email delivery monitoring system using AWS SES event logs

Mailing System Email Delivery Result Tracking FeatureInternal Seminar2024.02

Presented mailing system email delivery result tracking feature implementation and architecture

AWS SAA Study GroupStudy Group2023.09 ~ 2023.12

Internal study group for cloud architecture deep dive

Medgo

Dev Team Backend Engineer

2022.04 — 2023.06

Telemedicine and medication delivery platform startup with 300K cumulative downloads

Highlights

  • •Auth, appointment, and notification changes risked regressions in a single Express app.js. 3-stage progressive migration (single-file→layered→NestJS) + JS→TS. Reached 80% test coverage and established module/layer boundaries and team coding conventions.
  • •Manual prescription entry bottleneck (3-5min per case). Naver Clova OCR + MFDS (Korea FDA) API integration for full workflow automation. Pharmacist processing time 3–5min→30sec per prescription.
  • •Status reflection delay in consultation/dispensing/delivery (tens of seconds). Socket.IO real-time sync + Web Push notifications. Reduced to under 1 second, eliminated patient wait complaints.

Projects

Auth Server Development

2022.04 (3 weeks)

Built JWT-based unified authentication system to resolve subdomain session conflicts

  • •No unified authentication system for multi-subdomain architecture — Designed and implemented NestJS + JWT token authentication system, Unified auth across web (doctor/pharmacist/admin) + mobile app
  • •Session-based auth causing subdomain transition failures — Migrated from session-based to token-based authentication, Implemented seamless user transitions across subdomains

Tech Rationale

Structurally resolved subdomain cookie-based session conflicts with stateless JWT tokens. Chose MySQL over Redis for key management — Redis deemed over-engineering given traffic volume, prioritizing infrastructure simplicity.

Contribution: Independently designed and implemented over 3 weeks. Covered entire auth system for web (doctor/pharmacist/admin portals) + mobile app.

NestJSTypeScriptJWTMySQL

Common Module Development

2022.05 ~ 2022.06

Resolved code duplication and inconsistency from independent service management by consolidating shared modules

  • •No centralized permission verification across services — Implemented user permission verification middleware, Enhanced security with unified access control
NestJSTypeScript

Doctor/Pharmacist Web Service Enhancement

2022.04 ~ 2023.05

Eliminated manual notification workflows and lack of real-time status updates in doctor/pharmacist back-office systems by introducing Socket.io and Web Push

  • •Duplicate appointment bookings causing scheduling conflicts — Implemented Doctor ID + time slot composite unique key constraint, Prevented duplicate appointments at the database level
  • •Status reflection delay (tens of seconds) in consultation/dispensing/delivery — Deployed Socket.IO Room-based real-time status sync reflecting events to relevant users instantly, Reduced delay to under 1 second, eliminated patient wait complaints
  • •External service failures (delivery, payment) cascading to main application — Architected internal API gateway integrating delivery (Hoodadak) and payment services with Circuit Breaker pattern, Isolated external-service faults to stop cascading failures

Tech Rationale

Used Socket.IO Room-based event isolation for real-time consultation/dispensing/delivery status sync. Integrated API gateway + Circuit Breaker to prevent external service failure propagation. Enforced duplicate reservation prevention via DB composite unique key.

Contribution: Directly implemented Socket.IO real-time sync, Web Push notifications, API gateway, and reservation dedup in 2-person BE team.

Express.jsNestJSTypeScriptEJSMySQLSocket.ioWeb Push

Prescription OCR & Medication Guide System

2022.11 ~ 2022.12

Automated pharmacist's manual prescription entry process using OCR

  • •Manual prescription text entry from images (3-5 min per case) — Integrated Naver Clova OCR API for automatic text extraction from prescription images, Automated prescription data entry
  • •Manual medication guide creation inefficiency — Developed automated medication guide generation using MFDS (Korea FDA) drug information API, Pharmacist processing time 3–5min→30sec per prescription

Tech Rationale

Selected Naver Clova OCR for Korean pharmaceutical terminology recognition. Integrated MFDS public data API instead of building proprietary drug database to minimize maintenance overhead.

Contribution: Independently implemented over 2 months. Built entire pipeline: image intake → OCR extraction → MFDS API matching → medication guide generation.

NestJSTypeScriptNaver Clova OCRMySQL

Backend Architecture Migration

2023.03 ~ 2023.05

Migrated from Express.js single-file (app.js) structure to NestJS modular architecture

  • •Express.js single-file (app.js) 10,000-line codebase unmaintainable — Executed 3-phase incremental migration: app.js single file → Layered Architecture (Controller/Service/Repository) → NestJS framework adoption, Migrated a 10,000-line single file to NestJS modules and established team coding conventions
  • •JavaScript code lacked type safety — Migrated JavaScript → TypeScript, Improved type safety
  • •Regression risk without tests — Introduced TDD and unit tests, Achieved 80% test coverage

Tech Rationale

Adopted NestJS DI/module system to resolve maintainability limits of 10,000-line Express single-file legacy. Minimized risk via 3-phase gradual migration (single file → layered → NestJS). Introduced TDD to prevent regression during migration.

Contribution: Led independently. Performed all 3 migration phases, JS→TS migration, TDD adoption, and team coding convention establishment.

NestJSTypeScriptTypeORMJestMySQL

SimpleHAN

Dev Team Backend Engineer

2021.07 — 2022.03

Custom software consulting firm

Highlights

  • •Manual learning management (attendance, completion, progress tracking). Built LMS full-stack (QR attendance, PDF certificates, Excel bulk registration). Digitized operations for 300+ students per semester.
  • •Adding matching and counseling to legacy PHP risked regressions. Integrated an independent Spring Boot app via an iframe/postMessage boundary with weighted-average matching. Launched the JOB Agent service while isolating the legacy-system impact surface.

Projects

Learning Management System (LMS) Development

2021.07 ~ 2022.03

Resolved manual learning management (attendance, completion, progress) causing low operational efficiency and frequent errors at educational institutions

  • •Manual attendance tracking prone to duplicates and errors — Built QR attendance API with date+userID composite unique key preventing duplicate check-ins, Automated attendance tracking and prevented duplicate check-ins
  • •Inefficient individual student registration — Built Apache POI-based Excel bulk registration with row-by-row sequential processing to preserve data consistency, Supported bulk registration for 300+ students per semester
  • •Manual certificate generation workflow — Built JasperReports-based PDF auto-generation API, Automated dynamic certificate creation

Tech Rationale

Selected Java/Spring Boot as enterprise standard for educational institution delivery. Enforced QR attendance dedup via DB composite unique key (date+userID). Used JasperReports for template-based bulk PDF certificate generation.

Contribution: Directly implemented core features: QR attendance, Excel batch registration, PDF certificates, progress tracking. Responsible for backend development in a 6-person full-stack team.

JavaSpring BootMyBatisMySQLApache POIJasperReports

Incheon Smart Green Industrial Complex Control Center

2022.01 ~ 2022.03

Resolved fragmented reservation, monitoring, and SMS systems preventing unified management at industrial complex control center

  • •Scheduling conflicts from concurrent facility reservations — Built real-time booking API with time+location composite unique key, Prevented scheduling conflicts at the database level
  • •Synchronous SMS sending blocking reservation confirmation flow — Implemented Bizppurio SMS API + @Async non-blocking notification, Moved reservation-confirmation SMS to asynchronous delivery

Tech Rationale

Enforced meeting room booking conflict prevention via DB composite unique key (time+location). Used @Async for SMS to resolve API response delay — separate message queue deemed over-engineering for the traffic scale.

Contribution: Responsible for backend development. Directly implemented reservation API, dashboard monitoring API, and async SMS integration.

JavaSpring BootMySQLBizppurio SMS API

Future Service JOB Agent Development

2021.07 ~ 2022.03

Resolved legacy PHP system's extensibility limitations and lack of structured scoring and counseling management

  • •Legacy PHP system could not be extended for new features — Embedded Spring Boot independent app via iframe integration, minimizing legacy impact, Launched JOB Agent service without disrupting existing system
  • •No structured scoring system for multi-dimensional assessments — Implemented weighted average-based composite scoring algorithm, Delivered standardized multi-dimensional assessment scoring

Tech Rationale

Embedded independent Spring Boot app via iframe for non-invasive legacy PHP system extension. Used postMessage API for cross-frame communication. Implemented weighted average algorithm for multi-dimensional evaluation scoring.

Contribution: Responsible for backend development. Designed iframe integration, implemented weighted scoring algorithm, postMessage state sync, and counselor back-office.

JavaSpring BootMySQL

kfriends Member Management System

2021.09 (3 weeks)

Resolved lack of unified authentication requiring separate logins across 5 country-specific distributed websites

  • •Separate logins required across 5 country-specific websites — Built unified auth server with Spring Security + JWT-based centralized authentication, Brought single sign-on to all 5 country sites

Tech Rationale

Resolved fragmented login across 5-country websites with centralized JWT-based unified auth server. Configured CORS multi-domain handling for cross-origin authentication.

Contribution: Independently implemented over 3 weeks. Built entire unified auth server.

JavaSpring BootSpring SecurityJWTMySQL

Internal Tech Blog Renewal

2021.09 (3 weeks)

Resolved hosting cost burden and manual deployment workflow of WordPress-based blog

  • •WordPress hosting cost burden and manual deployment workflow — Migrated WordPress → Jekyll with static site generation, Eliminated 100% hosting costs with automated deployment
JekyllLiquidTravis CIGitHub Pages

Personal Projects (Side)

Platform / Tooling Engineering

2026.04 — Present

Self-directed platform/tooling engineering outside work — development workflow automation framework and side projects

Projects

Public AI CLI Runtime Launcher

2026.04 ~ Present

A public launcher managing project-scoped execution boundaries for Claude Code, Codex, Kiro, and OMP, with a durable queue for ordered delivery of parallel work

  • •Shared global AI CLI state and profile inference from names or remotes risked mixing sessions and rules or starting in the wrong workspace — Generated project-scoped runtime homes and implemented harness-auto to select only the single most-specific registered boundary from the canonical current path, Blocked outside paths, symlink escapes, and ambiguous registrations before startup; public contract demo and CI reproduce boundary, source SHA-256, and relationship-integrity checks
  • •Holding a shared lock through validation, push, and readback left parallel integration waits failing even after 600 and 3,600 seconds — Separated durable enqueue/wait and implemented cross-pool per-destination FIFO, idempotent submission, worker/test budgets, frozen snapshots, and crash-after-push reconciliation, Both real jobs from two pools reached DELIVERED on attempt 1 with exit 0; duplicate submissions returned the same ID and wait timeout left jobs queued; public PR #146 preserves implementation evidence
  • •OMP's local fork and mismatched HOME, authentication, and resume metadata interrupted shared execution or bypassed tool policy — Replaced the local fork with upstream extensions and configuration overlays; unified runtime, auth/resume, URL-read, pre-model-call, terminal-process, and termination-signal policies, On v0.77.7, confirmed 0 GETs to denied native URL targets, 0 provider calls on print denial, and Ctrl-C exit 130 with 0 remaining native processes; upstream MCP/LSP activation and full global DB SSOT remain outside this scope

Tech Rationale

Uses canonical path ownership for execution boundaries and separates durable submission from completion with per-destination FIFO instead of long-held shared locks. Integrates OMP through upstream trusted extensions, configuration overlays, and a thin adapter rather than local fork patches.

Claude CodeZshBashPythonHomebrewGitHub ActionsMCP

Job Posting Aggregation Platform

2026.04 ~ Present

Built the deployment and scheduling infrastructure for a side project that auto-collects and normalizes job postings

  • •Free-tier hosting lacked cron support and the managed DB's free tier auto-paused, blocking scheduled jobs — Adopted a self-hosted Mac mini workflow-automation (n8n) scheduler instead of hosting cron, and standardized warm-up endpoints and secrets, Kept the free tier alive via daily DB warm-up and restructured manifest-based sync
TypeScriptSupabasen8nVercel