Skip to content

Commit 15466c0

Browse files
authored
Merge pull request #97 from wellwind/codex/determine-next-steps-after-reviewing-clean-architecture-plan
feat: scaffold shared core contracts for phase 1
2 parents fb6a368 + d8307e1 commit 15466c0

34 files changed

+126
-62
lines changed

AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# 協作指引
2+
3+
- 每次變更若累計 diff 大於 ±400 行,必須立即暫停後續開發,先提交 PR,並在文件中明確記錄尚未完成的事項。
4+
- 所有已提交至版本庫的變更,都必須建立對應的 PR;未建立 PR 不得視為任務完成。

docs/clean-architecture-plan.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ src/
109109
- [ ] Wire the Node-driven Jasmine runner into CI after confirming compatible Node and dependency versions in the target environment.
110110

111111
### Phase 1 – Shared Core & Contracts
112-
- Create `shared/core` with existing `PostMeta`, `Category`, `Tag`, date utilities, Markdown parsing contracts.
113-
- Introduce testing builders/mocks in `shared/testing` to support upcoming migrations.
114-
- Define cross-feature ports (`AnalyticsPort`, `PlatformPort`, `SeoMetaPort`) in `shared/core/ports` so features can consume them consistently.
112+
- ✅ 建立 `shared/core` 骨架並搬遷 `PostMeta`/分類/標籤型別,新增 `@shared/core``@shared/testing` path alias 供程式與測試共用。
113+
- ✅ 在 `shared/testing` 提供 `postMetaBuilder`,開始以共用 builder 取代既有測試內的臨時工廠函式。
114+
- ⏳ 定義跨切片 ports`AnalyticsPort``PlatformPort``SeoMetaPort`)並提供暫行實作;後續將補齊 Markdown/日期契約與其適配層。
115115

116116
### Phase 2 – Scaffold Feature Slices
117117
- Create directory skeletons for `blog`, `post-detail`, `search`, `taxonomy`, `layout` mirroring the proposed structure.

docs/phase-1-plan.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Phase 1:Shared Core 與契約落地計畫
2+
3+
## 目標
4+
- 建立 `src/shared/core` 架構,收納跨切片共用的模型、日期工具與 Markdown 契約,並提供乾淨的公開 API。
5+
- 建立 `src/shared/testing`,集中共用的 builders 與 mocks,以利後續各切片測試重用。
6+
- 定義 `AnalyticsPort``PlatformPort``SeoMetaPort` 等跨功能介面,為後續功能切片鋪設穩定契約。
7+
8+
## 工作分解與狀態
9+
- [x] 盤點並記錄現存跨切片模型與工具,整理移轉清單。
10+
- [x] 建立 `shared/core` 目錄骨架與 `index.ts` 桶狀匯出,準備 `models/``markdown/``dates/``ports/` 子目錄。
11+
- [x] 搬遷 `PostMeta`、分類/標籤型別至共享模型,並更新現有呼叫端引用。
12+
- [x] 規劃 Markdown 與日期相關契約的遷移策略,並準備空殼模組待後續填補。
13+
- [x] 建立 `shared/testing` 的 builders/mocks 架構,並將既有測試改用共用 `postMetaBuilder`
14+
- [ ] 定義並匯出跨切片 ports 的介面與暫行實作。
15+
- [x] 更新 `tsconfig` path alias 與相關建置腳本,確保新路徑可用。
16+
- [x] 調整 `docs/clean-architecture-plan.md` 與其他文件,反映 Phase 1 的實作現況與剩餘工作。
17+
18+
## 測試策略
19+
- 每完成一個主要子任務,至少執行 `npm run lint` 驗證程式碼靜態品質,必要時補跑 `npm run test` 確認回歸測試。
20+
- 建立新的共用 builders 或 ports 後,新增或調整單元測試,確保行為維持正確。
21+
22+
## 風險與緩解
23+
- **變更多點**:拆分提交,必要時提早提交 PR,避免超出 ±400 行限制。
24+
- **匯入路徑錯誤**:調整完成後以 TypeScript 編譯與 lint 驗證,並透過 IDE/CI 觀察潛在錯誤。
25+
- **測試資源遷移造成回歸**:每次替換測試 helper 後立即執行相關單元測試。
26+
27+
## 里程碑追蹤
28+
- 2024-??-??:建立共享架構(進行中)。
29+
- 2024-??-??:完成核心模型搬遷(未開始)。
30+
- 2024-??-??:完成 ports 定義與共用測試資源(未開始)。
31+
32+
## 進度紀錄
33+
- 2025-09-19:完成 `PostMeta` 模型搬遷與 `shared/core` 骨架建立,新增 `@shared/core``@shared/testing` path alias,並以 `postMetaBuilder` 取代部份測試中的臨時建構函式。已執行 `npm run lint``npm run test` 確認既有流程穩定,尚待定義跨切片 ports 與補齊 Markdown/日期契約實作,文件同步更新進行中。

src/app/blog/blog-archives/blog-archives-posts-resolve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable, inject } from '@angular/core';
2+
import { PostMetaWithSlug } from '@shared/core';
23
import { Observable } from 'rxjs';
3-
import { PostMetaWithSlug } from '../../site-common/post-meta.interface';
44
import { SitePostService } from '../../site-common/site-post.service';
55

66
@Injectable({

src/app/blog/blog-archives/blog-archives.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { MatCardModule } from '@angular/material/card';
44
import { MatIconModule } from '@angular/material/icon';
55
import { MatToolbarModule } from '@angular/material/toolbar';
66
import { RouterLink } from '@angular/router';
7+
import { PostMetaWithSlug } from '@shared/core';
78
import { getRouteData, getRouteParam } from 'src/app/site-common/route-utils';
89
import { BlogPostSubtitleComponent } from '../../site-common/blog-post-subtitle.component';
910
import { PaginationComponent } from '../../site-common/pagination.component';
1011
import { PostDateAsPathPipe } from '../../site-common/post-date-as-path.pipe';
11-
import { PostMetaWithSlug } from '../../site-common/post-meta.interface';
1212
import { getPagePosts } from '../get-page-posts';
1313

1414
const PAGE_SIZE = 10;

src/app/blog/blog-categories/blog-categories-posts-resolve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Injectable, inject } from '@angular/core';
22
import { ActivatedRouteSnapshot } from '@angular/router';
33
import { descend, prop, sortWith } from 'ramda';
4+
import { PostMetaWithSlug } from '@shared/core';
45
import { Observable, map } from 'rxjs';
5-
import { PostMetaWithSlug } from '../../site-common/post-meta.interface';
66
import { SitePostService } from '../../site-common/site-post.service';
77
import { findPosts } from '../find-posts';
88

src/app/blog/blog-categories/blog-categories-posts.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { MatCardModule } from '@angular/material/card';
1010
import { MatIconModule } from '@angular/material/icon';
1111
import { MatToolbarModule } from '@angular/material/toolbar';
1212
import { RouterLink } from '@angular/router';
13-
import { PostMetaWithSlug } from 'src/app/site-common/post-meta.interface';
13+
import { PostMetaWithSlug } from '@shared/core';
1414
import { getRouteData, getRouteParam } from 'src/app/site-common/route-utils';
1515
import { BlogPostSubtitleComponent } from '../../site-common/blog-post-subtitle.component';
1616
import { PaginationComponent } from '../../site-common/pagination.component';

src/app/blog/blog-categories/blog-categories-resolve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable, inject } from '@angular/core';
2+
import { PostMetaWithSlug } from '@shared/core';
23
import { Observable } from 'rxjs';
3-
import { PostMetaWithSlug } from '../../site-common/post-meta.interface';
44
import { SitePostService } from '../../site-common/site-post.service';
55

66
@Injectable({

src/app/blog/blog-categories/blog-categories.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
} from '@angular/core';
88
import { MatCardModule } from '@angular/material/card';
99
import { RouterLink } from '@angular/router';
10+
import { PostMetaWithSlug } from '@shared/core';
1011
import { getRouteData } from 'src/app/site-common/route-utils';
11-
import { PostMetaWithSlug } from '../../site-common/post-meta.interface';
1212
import { SiteMetaService } from '../../site-common/site-meta.service';
1313
import { SlugifyPipe } from '../../site-common/slugify.pipe';
1414

src/app/blog/blog-posts/blog-post/blog-post.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { MatIconModule } from '@angular/material/icon';
1414
import { MatTooltipModule } from '@angular/material/tooltip';
1515
import { DomSanitizer } from '@angular/platform-browser';
1616
import { RouterLink } from '@angular/router';
17+
import { PostMetaWithSlug } from '@shared/core';
1718
import { MarkdownMeta } from 'site-utils';
1819
import { getRouteData } from 'src/app/site-common/route-utils';
1920
import { findMainContentContainer, scrollTo } from '../../../../utils';
@@ -22,7 +23,6 @@ import { CommentComponent } from '../../../site-common/comment.component';
2223
import { LikerCoinComponent } from '../../../site-common/liker-coin.component';
2324
import { PlatformService } from '../../../site-common/platform.service';
2425
import { PostDateAsPathPipe } from '../../../site-common/post-date-as-path.pipe';
25-
import { PostMetaWithSlug } from '../../../site-common/post-meta.interface';
2626
import { SiteMetaService } from '../../../site-common/site-meta.service';
2727
import { SitePostService } from '../../../site-common/site-post.service';
2828
import { SlugifyPipe } from '../../../site-common/slugify.pipe';

0 commit comments

Comments
 (0)