From ca1198108bc1b222f8319c726992b4a2e4de6f50 Mon Sep 17 00:00:00 2001 From: Sin-Kang Date: Sun, 30 Aug 2026 20:52:22 +0900 Subject: [PATCH 1/2] feat: apply DevsLab OSS identity to api-log --- .github/assets/readme-header.png | Bin 0 -> 9820 bytes .github/assets/social-preview.png | Bin 0 -> 14544 bytes README.ko.md | 6 +++ README.md | 6 +++ docs/assets/favicon.svg | 1 + docs/assets/logo.svg | 4 +- docs/assets/social-preview.png | Bin 0 -> 14544 bytes docs/index.ko.md | 5 ++ docs/index.md | 5 ++ docs/overrides/main.html | 12 +++++ docs/stylesheets/extra.css | 56 ++++++++++++++++++++ mkdocs.yml | 3 +- scripts/check-brand-assets.mjs | 84 ++++++++++++++++++++++++++++++ 13 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 .github/assets/readme-header.png create mode 100644 .github/assets/social-preview.png create mode 100644 docs/assets/favicon.svg create mode 100644 docs/assets/social-preview.png create mode 100644 docs/overrides/main.html create mode 100644 scripts/check-brand-assets.mjs diff --git a/.github/assets/readme-header.png b/.github/assets/readme-header.png new file mode 100644 index 0000000000000000000000000000000000000000..ca754a4b2610b3641a713a973bac0371d6811ff2 GIT binary patch literal 9820 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 literal 0 HcmV?d00001 diff --git a/.github/assets/social-preview.png b/.github/assets/social-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..c15437449fa5a84b52b9039a1fb118b77df3e680 GIT binary patch literal 14544 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 P58$HlmGdP=&cFR10(|q5 literal 0 HcmV?d00001 diff --git a/README.ko.md b/README.ko.md index 60bbeca..cb90481 100644 --- a/README.ko.md +++ b/README.ko.md @@ -1,5 +1,11 @@ # api-log-spring-boot-starter +

+ api-log - DevsLab 오픈소스 +

+ +**[DevsLab 오픈소스](https://devslab.kr/)** · [OSS 브랜드 가이드](https://devslab.kr/brand/open-source/) · Registry O09 + [English](README.md) · **한국어** > Spring Boot용 이벤트 드리븐 API 호출 로깅. 비동기 이벤트 파이프라인 + PostgreSQL JSONB. 요청 경로를 막지 않고 외부 API 호출을 모두 기록합니다. diff --git a/README.md b/README.md index 3938fab..bc0a3c9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # api-log-spring-boot-starter +

+ api-log - Open source by DevsLab +

+ +**Open source by [DevsLab](https://devslab.kr/)** · [OSS brand guide](https://devslab.kr/brand/open-source/) · Registry O09 + **English** · [한국어](README.ko.md) > Event-driven API call logging for Spring Boot. Async event pipeline with PostgreSQL JSONB storage. diff --git a/docs/assets/favicon.svg b/docs/assets/favicon.svg new file mode 100644 index 0000000..c16d18c --- /dev/null +++ b/docs/assets/favicon.svg @@ -0,0 +1 @@ +api-log \ No newline at end of file diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg index 188ac30..c16d18c 100644 --- a/docs/assets/logo.svg +++ b/docs/assets/logo.svg @@ -1,3 +1 @@ - - - +api-log \ No newline at end of file diff --git a/docs/assets/social-preview.png b/docs/assets/social-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..c15437449fa5a84b52b9039a1fb118b77df3e680 GIT binary patch literal 14544 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 P58$HlmGdP=&cFR10(|q5 literal 0 HcmV?d00001 diff --git a/docs/index.ko.md b/docs/index.ko.md index 5d70dd4..fb88549 100644 --- a/docs/index.ko.md +++ b/docs/index.ko.md @@ -4,6 +4,11 @@ title: api-log — Spring Boot용 이벤트 드리븐 API 호출 로깅 # api-log + + + api-logDevsLab 오픈소스 + + > **Spring Boot용 이벤트 드리븐 API 호출 로깅.** > 비동기 이벤트 파이프라인 + PostgreSQL JSONB. 요청 경로를 막지 않고 외부 API 호출을 모두 기록합니다. diff --git a/docs/index.md b/docs/index.md index c06f493..5f47d84 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,6 +4,11 @@ title: api-log — Event-driven API call logging for Spring Boot # api-log + + + api-logOpen source by DevsLab + + > **Event-driven API call logging for Spring Boot.** > Async event pipeline + PostgreSQL JSONB. Log every outbound call without slowing the request path. diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 0000000..05a9b2e --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block site_meta %} + {{ super() }} + + + + + + + +{% endblock %} diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 40cd97f..1ebe889 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -241,3 +241,59 @@ html[lang="ko"] .md-header [aria-label="Select language"]::before, html[lang="ko"] .md-header [aria-label*="언어"]::before { content: "한"; } + +/* === O09 project identity ================================================== + * The event-ledger mark stays a small, linked source of provenance above the + * existing documentation hero. The atmosphere is decorative only. + * ========================================================================== */ +.oss-project-intro { + position: relative; + isolation: isolate; + display: inline-flex; + align-items: center; + gap: 0.65rem; + min-height: 2.5rem; + margin: 0 0 0.85rem; + padding: 0.35rem 0.55rem 0.35rem 0.4rem; + overflow: hidden; + border-radius: 0.4rem; + color: var(--md-default-fg-color); + text-decoration: none; +} + +.oss-project-intro:hover, +.oss-project-intro:focus { + color: var(--md-default-fg-color); + text-decoration: none; +} + +.oss-project-intro[data-atmosphere="project"]::before { + position: absolute; + inset: -1.75rem -3.5rem; + z-index: -1; + pointer-events: none; + background: radial-gradient(ellipse at 18% 50%, rgb(14 116 144 / 0.10), transparent 68%); + content: ""; +} + +.oss-project-intro img { + width: 2rem; + height: 2rem; + flex: none; +} + +.oss-project-intro span { + display: grid; + line-height: 1.2; +} + +.oss-project-intro strong { font-size: 0.9rem; } +.oss-project-intro small { color: var(--md-default-fg-color--light); font-size: 0.72rem; } + +[data-md-color-scheme="slate"] .oss-project-intro[data-atmosphere="project"]::before { + background: radial-gradient(ellipse at 18% 50%, rgb(34 211 238 / 0.10), transparent 68%); +} + +@media (forced-colors: active), print { + .oss-project-intro[data-atmosphere="project"]::before { display: none; } +} diff --git a/mkdocs.yml b/mkdocs.yml index 9c55d5d..acbc421 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,9 +12,10 @@ docs_dir: docs theme: name: material + custom_dir: docs/overrides language: en logo: assets/logo.svg - favicon: assets/logo.svg + favicon: assets/favicon.svg features: - navigation.tabs - navigation.sections diff --git a/scripts/check-brand-assets.mjs b/scripts/check-brand-assets.mjs new file mode 100644 index 0000000..9ee6d22 --- /dev/null +++ b/scripts/check-brand-assets.mjs @@ -0,0 +1,84 @@ +import { createHash } from 'node:crypto'; +import { access, readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const guide = 'https://devslab.kr/brand/open-source/'; +const socialImage = 'https://api-log.devslab.kr/assets/social-preview.png'; +const read = (relative) => readFile(path.join(root, relative), 'utf8'); +const file = (relative) => path.join(root, relative); + +function expect(contents, expected, message) { + if (!contents.includes(expected)) throw new Error(`${message}: expected ${JSON.stringify(expected)}`); +} + +function reject(contents, pattern, message) { + if (pattern.test(contents)) throw new Error(message); +} + +async function sha256(relative) { + return createHash('sha256').update(await readFile(file(relative))).digest('hex'); +} + +const expectedAssets = new Map([ + ['.github/assets/readme-header.png', 'fea39433ffb685add26050558b2758858610be982f893014a1eead2d5469fbcc'], + ['.github/assets/social-preview.png', '3120931330d7604cda9ee4aa27d42e849e9f05f24cd8cb50b95e389d97a86842'], + ['docs/assets/logo.svg', '94697c47e87ac17d9209b890da0993b9d85c04ddb2d91b27afc7cfc31dc0380d'], + ['docs/assets/favicon.svg', '94697c47e87ac17d9209b890da0993b9d85c04ddb2d91b27afc7cfc31dc0380d'], + ['docs/assets/social-preview.png', '3120931330d7604cda9ee4aa27d42e849e9f05f24cd8cb50b95e389d97a86842'], +]); + +for (const [relative, expected] of expectedAssets) { + await access(file(relative)); + if ((await sha256(relative)) !== expected) throw new Error(`${relative} must match the O09 v0.1.1 asset checksum`); +} + +const glyph = await read('docs/assets/logo.svg'); +expect(glyph, 'data-oss-project="O09"', 'O09 registry id'); +expect(glyph, 'M5 8H13', 'O09 event-ledger input row'); +expect(glyph, 'M15 6H27V12H15Z', 'O09 event-ledger record cell'); +reject(glyph, /M\s*4\s*4\s*L\s*28\s*4/i, 'O09 must replace the former shared backend mark'); +reject(glyph, /M7 6H21V20H7Z/i, 'O09 must remain distinct from O08'); +reject(glyph, /M5 5H13V13H5Z/i, 'O09 must remain distinct from O10'); + +const [readme, readmeKo, mkdocs, index, indexKo, override, css] = await Promise.all([ + read('README.md'), + read('README.ko.md'), + read('mkdocs.yml'), + read('docs/index.md'), + read('docs/index.ko.md'), + read('docs/overrides/main.html'), + read('docs/stylesheets/extra.css'), +]); + +for (const [relative, contents, endorsement] of [ + ['README.md', readme, 'Open source by DevsLab'], + ['README.ko.md', readmeKo, 'DevsLab 오픈소스'], +]) { + expect(contents, '.github/assets/readme-header.png', `${relative} O09 README header`); + expect(contents, guide, `${relative} canonical OSS guide`); + expect(contents, endorsement, `${relative} localized endorsement`); +} + +for (const [relative, contents, endorsement] of [ + ['docs/index.md', index, 'Open source by DevsLab'], + ['docs/index.ko.md', indexKo, 'DevsLab 오픈소스'], +]) { + expect(contents, 'oss-project-intro', `${relative} O09 project introduction`); + expect(contents, guide, `${relative} canonical OSS guide`); + expect(contents, endorsement, `${relative} localized endorsement`); +} + +expect(mkdocs, 'custom_dir: docs/overrides', 'MkDocs override source'); +expect(mkdocs, 'favicon: assets/favicon.svg', 'MkDocs O09 favicon'); +expect(mkdocs, 'stylesheets/extra.css', 'MkDocs atmosphere stylesheet'); +expect(override, socialImage, 'source-only O09 social preview metadata'); +expect(override, 'og:image:alt', 'Open Graph alt metadata'); +expect(override, 'twitter:image:alt', 'Twitter alt metadata'); +expect(css, '.oss-project-intro', 'O09 docs project introduction styling'); +expect(css, 'data-atmosphere="project"', 'O09 project atmosphere'); +expect(css, 'pointer-events: none', 'O09 atmosphere ignores interaction'); +expect(css, '@media (forced-colors: active), print', 'O09 print and forced-colors fallback'); + +console.log(`check:brand: verified O09 event-ledger identity, metadata, and ${expectedAssets.size} checksummed v0.1.1 assets`); From a6589fe96687681e054698112188f5d942a1a742 Mon Sep 17 00:00:00 2001 From: Sin-Kang Date: Sun, 30 Aug 2026 21:42:29 +0900 Subject: [PATCH 2/2] fix: gate api-log OSS brand verification --- .github/workflows/ci.yml | 8 ++++++++ .github/workflows/release.yml | 8 ++++++++ scripts/check-brand-assets.mjs | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd945f6..af6de18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,14 @@ jobs: - name: Checkout uses: actions/checkout@v6 + - name: Set up Node 22 + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Verify DevsLab OSS brand assets + run: node scripts/check-brand-assets.mjs + - name: Set up JDK 21 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9866c2..54e86ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,14 @@ jobs: - name: Checkout uses: actions/checkout@v6 + - name: Set up Node 22 + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Verify DevsLab OSS brand assets + run: node scripts/check-brand-assets.mjs + - name: Set up JDK 21 uses: actions/setup-java@v5 with: diff --git a/scripts/check-brand-assets.mjs b/scripts/check-brand-assets.mjs index 9ee6d22..e830ce2 100644 --- a/scripts/check-brand-assets.mjs +++ b/scripts/check-brand-assets.mjs @@ -78,6 +78,10 @@ expect(override, 'og:image:alt', 'Open Graph alt metadata'); expect(override, 'twitter:image:alt', 'Twitter alt metadata'); expect(css, '.oss-project-intro', 'O09 docs project introduction styling'); expect(css, 'data-atmosphere="project"', 'O09 project atmosphere'); +const slateAtmosphere = `[data-md-color-scheme="slate"] .oss-project-intro[data-atmosphere="project"]::before { + background: radial-gradient(ellipse at 18% 50%, rgb(34 211 238 / 0.10), transparent 68%); +}`; +expect(css, slateAtmosphere, 'Material slate O09 atmosphere at the 0.10 cyan opacity cap'); expect(css, 'pointer-events: none', 'O09 atmosphere ignores interaction'); expect(css, '@media (forced-colors: active), print', 'O09 print and forced-colors fallback');