@leejungkiin/awkit 1.0.5 β†’ 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ # πŸ—οΈ Phase 1: Architecture (District View) β€” Android
2
+
3
+ > **Zoom Level:** 1 β€” Architecture Design
4
+ > **Goal:** Design overall architecture with UI-First build order. NO code bodies.
5
+ > **Input:** Completed App Map from Phase 0.
6
+ > **Output:** Architecture Blueprint document.
7
+
8
+ ---
9
+
10
+ ## β›” OUTPUT RULE
11
+
12
+ ```
13
+ βœ… ALLOWED: Architecture diagrams, layer maps, feature-to-file mapping, API endpoint tables
14
+ βœ… ALLOWED: File paths, package names, dependency lists
15
+ ⚠️ ALLOWED: build.gradle.kts skeleton (plugins + dependencies only)
16
+ ❌ BLOCKED: Function bodies, implementation details, actual Kotlin code
17
+ ```
18
+
19
+ ---
20
+
21
+ ## πŸ“‹ Sub-steps
22
+
23
+ ### 1.1: Layer Design
24
+
25
+ ```
26
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
27
+ β”‚ Presentation β”‚
28
+ β”‚ β”œβ”€β”€ screens/ ([N] screens) β”‚
29
+ β”‚ β”œβ”€β”€ navigation/ (NavGraph) β”‚
30
+ β”‚ β”œβ”€β”€ theme/ (Material 3) β”‚
31
+ β”‚ └── components/ (Shared composables)β”‚
32
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
33
+ β”‚ Domain β”‚
34
+ β”‚ β”œβ”€β”€ model/ ([N] business models) β”‚
35
+ β”‚ β”œβ”€β”€ repository/ ([N] interfaces) β”‚
36
+ β”‚ └── usecase/ ([N] use cases) β”‚
37
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
38
+ β”‚ Data β”‚
39
+ β”‚ β”œβ”€β”€ remote/ ([N] API services) β”‚
40
+ β”‚ β”œβ”€β”€ local/ (Room, DataStore) β”‚
41
+ β”‚ └── repository/ (implementations) β”‚
42
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
43
+ β”‚ DI / Utilities β”‚
44
+ β”‚ └── modules, extensions, crypto β”‚
45
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
46
+ ```
47
+
48
+ ### 1.2: Feature β†’ File Mapping
49
+
50
+ | Feature | Domain Model | Repository | UseCase | Screen | ViewModel |
51
+ |---------|-------------|-----------|---------|--------|-----------|
52
+ | Auth | User, Token | AuthRepo | LoginUC | Login | AuthVM |
53
+ | Home | Feed | HomeRepo | GetFeedUC | Home | HomeVM |
54
+ | ... | ... | ... | ... | ... | ... |
55
+
56
+ ### 1.3: API Endpoint Inventory
57
+
58
+ | # | Method | Endpoint | Auth | Request | Response | Notes |
59
+ |---|--------|----------|------|---------|----------|-------|
60
+ | 1 | POST | /auth/login | No | email, pwd | JWT | - |
61
+ | 2 | GET | /users/me | Bearer | - | User | - |
62
+
63
+ **How to find in Smali:**
64
+ ```
65
+ const-string β†’ "https://" or "http://" (base URL)
66
+ .field β†’ BASE_URL, API_URL
67
+ StringBuilder + append (endpoint construction)
68
+ Annotation patterns (@GET, @POST in retrofit)
69
+ ```
70
+
71
+ ### 1.4: Data Schema Inventory
72
+
73
+ | Model | Key Fields | Source | Storage |
74
+ |-------|-----------|--------|---------|
75
+ | User | id, name, email, avatar | API | Room + Memory |
76
+ | Settings | theme, language | Local | DataStore |
77
+
78
+ ### 1.5: Project Structure
79
+
80
+ ```
81
+ app/src/main/java/com/package/
82
+ β”œβ”€β”€ App.kt
83
+ β”œβ”€β”€ di/ (AppModule, NetworkModule, DatabaseModule)
84
+ β”œβ”€β”€ data/
85
+ β”‚ β”œβ”€β”€ remote/api/
86
+ β”‚ β”œβ”€β”€ remote/dto/
87
+ β”‚ β”œβ”€β”€ local/db/
88
+ β”‚ β”œβ”€β”€ local/datastore/
89
+ β”‚ └── repository/
90
+ β”œβ”€β”€ domain/
91
+ β”‚ β”œβ”€β”€ model/
92
+ β”‚ β”œβ”€β”€ repository/
93
+ β”‚ └── usecase/
94
+ β”œβ”€β”€ presentation/
95
+ β”‚ β”œβ”€β”€ navigation/
96
+ β”‚ β”œβ”€β”€ theme/
97
+ β”‚ β”œβ”€β”€ components/
98
+ β”‚ └── screens/
99
+ β”‚ β”œβ”€β”€ splash/
100
+ β”‚ β”œβ”€β”€ auth/
101
+ β”‚ β”œβ”€β”€ home/
102
+ β”‚ └── [feature]/
103
+ └── util/
104
+ ```
105
+
106
+ ### 1.6: Build Order (UI-First) ⭐
107
+
108
+ > **IMPORTANT:** UI-First build order β€” design and approve UI before coding logic.
109
+
110
+ ```
111
+ Foundation (one-time):
112
+ 1. 🟒 Project setup + DI skeleton + Theme/Design System
113
+ 2. 🟒 Navigation structure (routes, tab bar)
114
+
115
+ Per Feature (repeat for each):
116
+ 3. πŸ“ Blueprint: Contracts (models, repos, use cases, state)
117
+ 4. 🎨 UI Shell: Visual implementation + Resource extraction
118
+ 5. 🚦 GATE: User approve UI
119
+ 6. πŸ”¨ Logic: Domain β†’ Data β†’ ViewModel β†’ Wire UI
120
+ 7. πŸ§ͺ Test: Integration + Parity
121
+
122
+ Final (one-time):
123
+ 8. πŸ“¦ SDK Integration + Native libs
124
+ 9. βœ… Full Parity Check
125
+ ```
126
+
127
+ ### 1.7: Tech Stack Decisions
128
+
129
+ | Decision | Choice | Rationale |
130
+ |----------|--------|-----------|
131
+ | Image Loading | Coil | Modern, Compose-native |
132
+ | JSON | Kotlin Serialization | Type-safe, no reflection |
133
+ | ... | ... | ... |
134
+
135
+ ---
136
+
137
+ ## πŸ“Š Output: Architecture Blueprint
138
+
139
+ Use template from `templates/architecture.md`.
140
+
141
+ ---
142
+
143
+ ## βœ… Gate
144
+
145
+ ```
146
+ "πŸ—οΈ Architecture Blueprint xong.
147
+ Build order: UI-First per feature.
148
+ Anh muα»‘n bαΊ―t Δ‘αΊ§u tα»« feature nΓ o?
149
+ Em suggest: [Feature X] vΓ¬ [reason β€” e.g., nhiều feature khΓ‘c phα»₯ thuα»™c]."
150
+
151
+ β†’ User picks feature β†’ Phase 2 (Blueprint + UI Design)
152
+ β†’ User wants changes β†’ Adjust architecture
153
+ ```
154
+
155
+ ---
156
+
157
+ *Phase 1: Architecture β€” Design before you build, UI before logic*
@@ -0,0 +1,347 @@
1
+ # πŸ“ Phase 2: Blueprint + UI Design (Per Feature) β€” Android
2
+
3
+ > **Zoom Level:** 2 β€” Feature Detail
4
+ > **Goal:** Design contracts AND code UI visual shell for ONE feature.
5
+ > **Input:** Architecture Blueprint (Phase 1) + user's chosen feature.
6
+ > **Output:** Approved contracts + Working UI shell with mock data.
7
+
8
+ ---
9
+
10
+ ## β›” OUTPUT RULE
11
+
12
+ ```
13
+ PART A β€” Contracts (signatures only):
14
+ βœ… Interface signatures, data class definitions, sealed classes
15
+ βœ… Retrofit interface with @GET/@POST annotations (no body)
16
+ βœ… UiState sealed class, Event sealed class, Action sealed class
17
+ ❌ Function body implementations (use TODO())
18
+
19
+ PART B β€” UI (visual code):
20
+ βœ… Full Jetpack Compose code for screen
21
+ βœ… Hardcoded mock data (using UiState from Part A)
22
+ βœ… Real resources (icons, colors, images extracted in 2.7)
23
+ βœ… @Preview for ALL states (normal, loading, error, empty)
24
+ ❌ Real ViewModel connection β€” use parameter defaults
25
+ ❌ Real API calls
26
+ ❌ Business logic
27
+ ```
28
+
29
+ ---
30
+
31
+ ## πŸ“‹ Sub-steps
32
+
33
+ ### 2.1: Deep Smali Reading
34
+
35
+ Read Smali/Java files for the chosen feature.
36
+
37
+ **What to extract:**
38
+ - Class hierarchy (extends, implements)
39
+ - Field declarations β†’ model properties
40
+ - Method signatures β†’ API contracts
41
+ - String constants β†’ URLs, keys, messages
42
+ - Control flow β†’ business rules (document, don't code)
43
+
44
+ **Smali Quick Ref:**
45
+ ```
46
+ .field β†’ class fields (properties)
47
+ .method β†’ method start
48
+ .end method β†’ method end
49
+ invoke-virtual β†’ instance method call
50
+ invoke-static β†’ static method call
51
+ const-string β†’ string literal
52
+ new-instance β†’ object creation
53
+ if-eqz/if-nez β†’ conditional branches
54
+ ```
55
+
56
+ See `smali-reading-guide.md` for comprehensive guide.
57
+
58
+ ### 2.2: Domain Model Contracts
59
+
60
+ ```kotlin
61
+ // Domain model
62
+ data class User(
63
+ val id: String,
64
+ val fullName: String,
65
+ val email: String,
66
+ val avatarUrl: String?,
67
+ val isVerified: Boolean
68
+ )
69
+
70
+ // DTO (from API)
71
+ @Serializable
72
+ data class UserDto(
73
+ @SerialName("user_id") val userId: String,
74
+ @SerialName("full_name") val fullName: String,
75
+ @SerialName("email") val email: String,
76
+ @SerialName("avatar_url") val avatarUrl: String?,
77
+ @SerialName("is_verified") val isVerified: Boolean
78
+ )
79
+ ```
80
+
81
+ ### 2.3: Repository Contract
82
+
83
+ ```kotlin
84
+ interface AuthRepository {
85
+ suspend fun login(email: String, password: String): Result<User>
86
+ suspend fun register(name: String, email: String, password: String): Result<User>
87
+ suspend fun logout()
88
+ fun isLoggedIn(): Flow<Boolean>
89
+ fun getCurrentUser(): Flow<User?>
90
+ }
91
+ ```
92
+
93
+ ### 2.4: API Contract
94
+
95
+ ```kotlin
96
+ interface AuthApi {
97
+ @POST("auth/login")
98
+ suspend fun login(@Body request: LoginRequest): LoginResponse
99
+
100
+ @POST("auth/register")
101
+ suspend fun register(@Body request: RegisterRequest): RegisterResponse
102
+
103
+ @GET("auth/me")
104
+ suspend fun getCurrentUser(@Header("Authorization") token: String): UserDto
105
+ }
106
+ ```
107
+
108
+ ### 2.5: UseCase Signatures
109
+
110
+ ```kotlin
111
+ class LoginUseCase(private val authRepo: AuthRepository) {
112
+ suspend operator fun invoke(email: String, password: String): Result<User>
113
+ // Implementation: TODO()
114
+ }
115
+ ```
116
+
117
+ ### 2.6: UI State Design
118
+
119
+ ```kotlin
120
+ // State
121
+ data class LoginUiState(
122
+ val email: String = "",
123
+ val password: String = "",
124
+ val isLoading: Boolean = false,
125
+ val error: String? = null,
126
+ val isPasswordVisible: Boolean = false
127
+ )
128
+
129
+ // Events (one-time actions)
130
+ sealed interface LoginEvent {
131
+ data class NavigateToHome(val user: User) : LoginEvent
132
+ data class ShowSnackbar(val message: String) : LoginEvent
133
+ }
134
+
135
+ // Actions (user interactions)
136
+ sealed interface LoginAction {
137
+ data class UpdateEmail(val email: String) : LoginAction
138
+ data class UpdatePassword(val password: String) : LoginAction
139
+ data object TogglePasswordVisibility : LoginAction
140
+ data object Submit : LoginAction
141
+ }
142
+ ```
143
+
144
+ ### 2.7: Resource Extraction ⭐ (Before UI code!)
145
+
146
+ > **Why here?** UI code (2.8) needs real assets. If resources come later, UI will be full of placeholders β€” defeating the purpose of visual parity.
147
+
148
+ **Process:**
149
+ 1. Analyze layout XML to list needed resources:
150
+ ```bash
151
+ grep -o '@drawable/[a-z_]*' [apktool]/res/layout/activity_login.xml | sort -u
152
+ grep -o '@color/[a-z_]*' [apktool]/res/layout/activity_login.xml | sort -u
153
+ grep 'const-string' [apktool]/smali/.../LoginActivity.smali | grep -i string
154
+ ```
155
+ 2. Copy ONLY needed resources to new project
156
+ 3. Verify all resources compile
157
+
158
+ **Output:**
159
+ ```markdown
160
+ ### πŸ“¦ Resources for [Screen]
161
+ - Drawables: [list]
162
+ - Colors: [list]
163
+ - Strings: [list]
164
+ - Dimens: [list]
165
+ βœ… All accessible
166
+ ```
167
+
168
+ ### 2.8: UI Implementation β€” Visual Shell ⭐
169
+
170
+ > **Goal:** Code the screen with HARDCODED mock data. Pixel-perfect visual parity with original app.
171
+
172
+ **Rules:**
173
+ ```
174
+ βœ… MUST DO:
175
+ - Use UiState from 2.6 (hardcode sample values as defaults)
176
+ - Use REAL resources extracted in 2.7
177
+ - Display ALL visual elements from original app
178
+ - Match: spacing, font size, colors, icon placement
179
+ - Code ALL states: normal, loading, error, empty
180
+ - Create @Preview for each state
181
+
182
+ ❌ MUST NOT:
183
+ - Connect real ViewModel (use parameter defaults)
184
+ - Call real APIs
185
+ - Code business logic
186
+ - Use DI/injection
187
+ ```
188
+
189
+ **Pattern β€” Stateless Composable:**
190
+ ```kotlin
191
+ @Composable
192
+ fun LoginScreenContent(
193
+ uiState: LoginUiState = LoginUiState(), // Hardcoded default
194
+ onAction: (LoginAction) -> Unit = {} // No-op default
195
+ ) {
196
+ Scaffold { padding ->
197
+ Column(
198
+ modifier = Modifier
199
+ .fillMaxSize()
200
+ .padding(padding)
201
+ .padding(24.dp),
202
+ horizontalAlignment = Alignment.CenterHorizontally
203
+ ) {
204
+ // Logo β€” real resource from 2.7
205
+ Image(
206
+ painter = painterResource(R.drawable.app_logo),
207
+ contentDescription = null,
208
+ modifier = Modifier.size(120.dp)
209
+ )
210
+ Spacer(Modifier.height(48.dp))
211
+
212
+ // Email
213
+ OutlinedTextField(
214
+ value = uiState.email,
215
+ onValueChange = { onAction(LoginAction.UpdateEmail(it)) },
216
+ label = { Text("Email") },
217
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
218
+ modifier = Modifier.fillMaxWidth()
219
+ )
220
+ Spacer(Modifier.height(16.dp))
221
+
222
+ // Password with toggle
223
+ OutlinedTextField(
224
+ value = uiState.password,
225
+ onValueChange = { onAction(LoginAction.UpdatePassword(it)) },
226
+ label = { Text("Password") },
227
+ visualTransformation = if (uiState.isPasswordVisible)
228
+ VisualTransformation.None else PasswordVisualTransformation(),
229
+ trailingIcon = {
230
+ IconButton(onClick = { onAction(LoginAction.TogglePasswordVisibility) }) {
231
+ Icon(
232
+ imageVector = if (uiState.isPasswordVisible)
233
+ Icons.Default.VisibilityOff else Icons.Default.Visibility,
234
+ contentDescription = "Toggle password"
235
+ )
236
+ }
237
+ },
238
+ modifier = Modifier.fillMaxWidth()
239
+ )
240
+ Spacer(Modifier.height(32.dp))
241
+
242
+ // Login Button
243
+ Button(
244
+ onClick = { onAction(LoginAction.Submit) },
245
+ enabled = !uiState.isLoading,
246
+ modifier = Modifier.fillMaxWidth().height(50.dp)
247
+ ) {
248
+ if (uiState.isLoading) {
249
+ CircularProgressIndicator(
250
+ modifier = Modifier.size(24.dp),
251
+ color = MaterialTheme.colorScheme.onPrimary
252
+ )
253
+ } else {
254
+ Text("Login", style = MaterialTheme.typography.labelLarge)
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ // ===== PREVIEWS =====
262
+ @Preview(showBackground = true)
263
+ @Composable
264
+ private fun NormalPreview() {
265
+ AppTheme { LoginScreenContent(LoginUiState(email = "user@example.com")) }
266
+ }
267
+
268
+ @Preview(showBackground = true)
269
+ @Composable
270
+ private fun LoadingPreview() {
271
+ AppTheme { LoginScreenContent(LoginUiState(isLoading = true)) }
272
+ }
273
+
274
+ @Preview(showBackground = true)
275
+ @Composable
276
+ private fun ErrorPreview() {
277
+ AppTheme { LoginScreenContent(LoginUiState(error = "Invalid credentials")) }
278
+ }
279
+ ```
280
+
281
+ ### 2.9: Visual Parity Check ⭐
282
+
283
+ Compare UI shell with original app screenshot:
284
+
285
+ ```markdown
286
+ ### πŸ“Έ Visual Parity: [Screen Name]
287
+
288
+ Layout:
289
+ - [ ] Structure matches original (components, sections)
290
+ - [ ] Spacing between elements correct
291
+ - [ ] Alignment matches
292
+
293
+ Styling:
294
+ - [ ] Colors match (background, text, buttons, header)
295
+ - [ ] Typography matches (font size, weight)
296
+ - [ ] Icons/images correct and positioned
297
+ - [ ] Borders, shadows, rounded corners
298
+
299
+ States:
300
+ - [ ] Normal state displays correctly
301
+ - [ ] Loading state β€” progress in right position
302
+ - [ ] Error state β€” error message shows properly
303
+ - [ ] Empty state β€” guidance shown
304
+
305
+ Platform:
306
+ - [ ] Material 3 conventions followed
307
+ - [ ] Edge-to-edge / system bars handled
308
+ - [ ] Looks good on different screen sizes
309
+ ```
310
+
311
+ ---
312
+
313
+ ## πŸ“Š Output: Feature Blueprint + UI
314
+
315
+ Use template from `templates/blueprint.md`.
316
+
317
+ ---
318
+
319
+ ## βœ… Gate (MANDATORY)
320
+
321
+ ```
322
+ "πŸ“ Blueprint + UI cho [Feature] xong:
323
+
324
+ πŸ“ Contracts:
325
+ - [N] domain models
326
+ - [N] repository interfaces
327
+ - [N] use case signatures
328
+ - [N] API endpoints
329
+
330
+ 🎨 UI:
331
+ - [Screen] implemented with mock data
332
+ - Resources: [N] drawables, [N] strings, [N] colors
333
+ - Previews: [N] states (normal, loading, error, empty)
334
+
335
+ πŸ“Έ Visual Parity: [OK / cαΊ§n chỉnh X, Y, Z]
336
+
337
+ Anh xem UI + contracts α»•n khΓ΄ng?
338
+ β†’ βœ… Approve β†’ Phase 3 (Logic Build)
339
+ β†’ 🎨 Adjust UI β†’ fix then re-check
340
+ β†’ πŸ“ Adjust contracts β†’ revise blueprint"
341
+ ```
342
+
343
+ > ⚠️ **DO NOT proceed to Phase 3 until user approves BOTH UI and contracts.**
344
+
345
+ ---
346
+
347
+ *Phase 2: Blueprint + UI Design β€” See it before you code it*