Skip to content

Commit dda85ed

Browse files
authored
Merge pull request #10 from shirokun20/feat/multi-source-migration-phase-4
Feat/multi source migration phase 4
2 parents 48cd29c + 80dcb34 commit dda85ed

File tree

162 files changed

+45285
-1066
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+45285
-1066
lines changed

.github/workflows/build.yml

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Build and Upload APK
22

33
# Trigger only when merged to master branch
4+
# Send notifications to Telegram Channel (not personal chat)
5+
# Setup: Add bot as admin to channel, get channel ID (@channelname or -100XXXXXXXXX)
46
on:
57
push:
68
branches: [ master, 'release/*' ]
@@ -76,29 +78,33 @@ jobs:
7678
fi
7779
done
7880
79-
# Notify on build failure
81+
# Notify on build failure to Telegram Channel
8082
- name: Notify Build Failure
8183
if: failure()
8284
env:
8385
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
84-
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
86+
TELEGRAM_CHANNEL_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
8587
run: |
8688
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
87-
-d chat_id="$TELEGRAM_CHAT_ID" \
89+
-d chat_id="$TELEGRAM_CHANNEL_ID" \
8890
-d parse_mode="Markdown" \
8991
-d text="
90-
❌ Build Failed
91-
🔗 Commit: ${GITHUB_SHA::8}
92+
❌ *Build Failed*
93+
94+
📦 Project: Kuro-N
95+
🔗 Commit: \`${GITHUB_SHA::8}\`
9296
🌿 Branch: ${GITHUB_REF_NAME}
93-
🔍 Check: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}
97+
👤 Author: ${GITHUB_ACTOR}
98+
99+
🔍 [View Details](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})
94100
"
95101
96-
# Notify on build success
102+
# Notify on build success to Telegram Channel
97103
- name: Notify Build Success
98104
if: success()
99105
env:
100106
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
101-
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
107+
TELEGRAM_CHANNEL_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
102108
run: |
103109
# Collect APK information
104110
APK_INFO=""
@@ -121,35 +127,35 @@ jobs:
121127
done
122128
123129
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
124-
-d chat_id="$TELEGRAM_CHAT_ID" \
130+
-d chat_id="$TELEGRAM_CHANNEL_ID" \
125131
-d parse_mode="Markdown" \
126132
-d text="
127-
✅ Build Success
128-
🔗 Commit: ${GITHUB_SHA::8}
129-
🌿 Branch: ${GITHUB_REF_NAME}
130-
🎯 Trigger: ${GITHUB_EVENT_NAME}
133+
🎉 *Cihuyy ada update baru nih!*
131134
132-
📦 Generated APKs: ${APK_COUNT}
133-
💾 Total Size: ~${TOTAL_SIZE}MB
135+
� Kuro-N
136+
📦 APK tersedia: ${APK_COUNT}
137+
💾 Total: ~${TOTAL_SIZE}MB
134138
${APK_INFO}
135139
136-
⬆️ Uploading to Telegram...
137-
🔍 Details: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}
140+
⬇️ File lagi diupload, tunggu sebentar ya...
138141
"
139142
140-
# Upload APK to Telegram
141-
- name: Upload APK to Telegram
143+
# Upload APK to Telegram Channel
144+
- name: Upload APK to Telegram Channel
142145
if: success()
143146
env:
144147
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
145-
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
148+
TELEGRAM_CHANNEL_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
146149
run: |
147150
# Check if APK files exist
148151
if [ ! -d "apk-output" ] || [ -z "$(ls -A apk-output/*.apk 2>/dev/null)" ]; then
149152
echo "❌ No APK files found in apk-output/"
150153
exit 1
151154
fi
152155
156+
# Get version from pubspec.yaml for caption
157+
VERSION=$(grep '^version: ' pubspec.yaml | cut -d ' ' -f 2 | cut -d '+' -f 1)
158+
153159
# Priority: ARM64 > ARM > x86_64
154160
# Only upload ARM64 and ARM to save bandwidth and telegram storage
155161
# x86_64 is mainly for emulators/testing
@@ -168,14 +174,14 @@ jobs:
168174
169175
echo "📤 Uploading ARM64: $apk (${size_mb}MB)..."
170176
response=$(curl -s --max-time 600 --connect-timeout 60 --retry 3 --retry-delay 10 \
171-
-F chat_id="$TELEGRAM_CHAT_ID" \
177+
-F chat_id="$TELEGRAM_CHANNEL_ID" \
172178
-F document=@"$apk" \
173-
-F caption="📱 ARM64 APK (Recommended for modern devices)" \
179+
-F caption="📱 Kuro-N v${VERSION} - ARM64 | ✅ Recommended for modern devices (Android 5.0+) | 💾 ${size_mb}MB | 🔗 ${GITHUB_SHA::8}" \
174180
"https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendDocument")
175181
176182
if echo "$response" | grep -q '"ok":true'; then
177183
echo "✅ Successfully uploaded ARM64 APK"
178-
UPLOADED_COUNT=$((UPLOADED_COUNT + 1))
184+
UPLOADED_COUNT=$((UPLOADED_COUNT + 1))(${size_mb}MB)
179185
else
180186
echo "❌ Failed to upload: $response"
181187
exit 1
@@ -196,14 +202,14 @@ jobs:
196202
197203
echo "📤 Uploading ARM: $apk (${size_mb}MB)..."
198204
response=$(curl -s --max-time 600 --connect-timeout 60 --retry 3 --retry-delay 10 \
199-
-F chat_id="$TELEGRAM_CHAT_ID" \
205+
-F chat_id="$TELEGRAM_CHANNEL_ID" \
200206
-F document=@"$apk" \
201-
-F caption="📱 ARM APK (For older devices)" \
207+
-F caption="📱 Kuro-N v${VERSION} - ARMv7 | 📦 For older devices | 💾 ${size_mb}MB | 🔗 ${GITHUB_SHA::8}" \
202208
"https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendDocument")
203209
204210
if echo "$response" | grep -q '"ok":true'; then
205211
echo "✅ Successfully uploaded ARM APK"
206-
UPLOADED_COUNT=$((UPLOADED_COUNT + 1))
212+
UPLOADED_COUNT=$((UPLOADED_COUNT + 1))(${size_mb}MB)
207213
else
208214
echo "❌ Failed to upload: $response"
209215
exit 1
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
description: Complete feature and move to success - Phase 4 of workflow
3+
subtask: true
4+
return:
5+
- Verify all tests pass and code is clean.
6+
- Congratulate the user and summarize what was built!
7+
---
8+
# Complete Feature
9+
10+
You are finalizing a feature in NhasixApp.
11+
12+
## Feature to Complete
13+
> $ARGUMENTS
14+
15+
## Your Task
16+
17+
1. **Verify completion checklist**:
18+
- [ ] All tasks in progress document are `[x]` completed
19+
- [ ] `flutter test` passes
20+
- [ ] `flutter analyze` is clean
21+
- [ ] Code follows conventions
22+
- [ ] No `print` statements (use logger)
23+
24+
2. **Run verification commands**:
25+
```bash
26+
flutter analyze
27+
flutter test
28+
```
29+
30+
3. **Update progress document** with completion summary:
31+
```markdown
32+
## Completion Summary
33+
34+
**Completed**: [Today's date]
35+
**Status**: ✅ Completed
36+
37+
### Deliverables
38+
- Feature X implemented
39+
- Y unit tests added
40+
41+
### Files Created/Modified
42+
- `lib/features/[feature]/...`
43+
```
44+
45+
4. **Move to success-plan**:
46+
```bash
47+
mv projects/onprogress-plan/$ARGUMENTS projects/success-plan/$ARGUMENTS
48+
```
49+
50+
5. **Register in DI** if not done:
51+
- Add to `core/di/injection_container.dart`
52+
53+
6. **Update any routes** if needed
54+
55+
## Final Checks
56+
- No TODO comments left
57+
- No debug code
58+
- Proper error handling
59+
- Documentation updated
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
description: Create a new Cubit with proper structure
3+
subtask: true
4+
return:
5+
- Register the Cubit in dependency injection.
6+
- Show example usage in a widget.
7+
---
8+
# Create Cubit
9+
10+
Create a new Cubit following NhasixApp conventions.
11+
12+
## Cubit Name
13+
> $ARGUMENTS
14+
15+
## Generated Files
16+
17+
1. **State file**: `[name]_state.dart`
18+
2. **Cubit file**: `[name]_cubit.dart`
19+
20+
## State Template (using freezed)
21+
22+
```dart
23+
import 'package:freezed_annotation/freezed_annotation.dart';
24+
25+
part '[name]_state.freezed.dart';
26+
27+
@freezed
28+
class [Name]State with _$[Name]State {
29+
const factory [Name]State.initial() = _Initial;
30+
const factory [Name]State.loading() = _Loading;
31+
const factory [Name]State.loaded(/* data */) = _Loaded;
32+
const factory [Name]State.error(String message) = _Error;
33+
}
34+
```
35+
36+
## Cubit Template
37+
38+
```dart
39+
import 'package:nhasixapp/core/base/base_cubit.dart';
40+
import '[name]_state.dart';
41+
42+
class [Name]Cubit extends BaseCubit<[Name]State> {
43+
final [UseCase] _useCase;
44+
45+
[Name]Cubit(this._useCase) : super(const [Name]State.initial());
46+
47+
Future<void> load() async {
48+
emit(const [Name]State.loading());
49+
50+
final result = await _useCase();
51+
52+
result.fold(
53+
(failure) => emit([Name]State.error(failure.message)),
54+
(data) => emit([Name]State.loaded(data)),
55+
);
56+
}
57+
}
58+
```
59+
60+
## DI Registration
61+
62+
```dart
63+
// In core/di/injection_container.dart
64+
sl.registerFactory(() => [Name]Cubit(sl()));
65+
```
66+
67+
Load skill: `skill({ name: "bloc-cubit" })`
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
description: Generate model from entity with all required methods
3+
subtask: true
4+
return:
5+
- Show the generated model code.
6+
- Remind to run build_runner if using freezed.
7+
---
8+
# Create Model
9+
10+
Generate a data model that extends an entity.
11+
12+
## Entity/Model Name
13+
> $ARGUMENTS
14+
15+
## Model Template
16+
17+
```dart
18+
import 'package:nhasixapp/features/[feature]/domain/entities/[name].dart';
19+
20+
class [Name]Model extends [Name] {
21+
const [Name]Model({
22+
required super.id,
23+
required super.field1,
24+
required super.field2,
25+
});
26+
27+
/// Create model from entity
28+
factory [Name]Model.fromEntity([Name] entity) {
29+
return [Name]Model(
30+
id: entity.id,
31+
field1: entity.field1,
32+
field2: entity.field2,
33+
);
34+
}
35+
36+
/// Convert to entity
37+
[Name] toEntity() {
38+
return [Name](
39+
id: id,
40+
field1: field1,
41+
field2: field2,
42+
);
43+
}
44+
45+
/// Create from JSON map
46+
factory [Name]Model.fromMap(Map<String, dynamic> map) {
47+
return [Name]Model(
48+
id: map['id'] as String,
49+
field1: map['field1'] as String,
50+
field2: map['field2'] as int,
51+
);
52+
}
53+
54+
/// Convert to JSON map
55+
Map<String, dynamic> toMap() {
56+
return {
57+
'id': id,
58+
'field1': field1,
59+
'field2': field2,
60+
};
61+
}
62+
63+
/// Create from JSON string
64+
factory [Name]Model.fromJson(String source) {
65+
return [Name]Model.fromMap(json.decode(source));
66+
}
67+
68+
/// Convert to JSON string
69+
String toJson() => json.encode(toMap());
70+
}
71+
```
72+
73+
## Required Methods Checklist
74+
75+
- [ ] `.fromEntity()` - Create model from entity
76+
- [ ] `.toEntity()` - Convert to entity
77+
- [ ] `.fromMap()` - Create from JSON map
78+
- [ ] `.toMap()` - Convert to JSON map
79+
- [ ] `.fromJson()` - Create from JSON string (optional)
80+
- [ ] `.toJson()` - Convert to JSON string (optional)
81+
82+
Load skill: `skill({ name: "clean-arch" })`

.opencode/commands/asix-develop.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
description: Full development workflow - analysis, plan, implement, complete
3+
subtask: true
4+
parallel:
5+
- command: asix-new-feature
6+
arguments: $ARGUMENTS
7+
return:
8+
- /asix-plan-feature $ARGUMENTS
9+
- /asix-start-feature $ARGUMENTS
10+
- /asix-complete-feature $ARGUMENTS
11+
---
12+
# Full Feature Development
13+
14+
This command orchestrates the complete feature development workflow:
15+
16+
1. **Analysis** → Create analysis document
17+
2. **Planning** → Create implementation plan
18+
3. **Implementation** → Build the feature
19+
4. **Completion** → Finalize and move to success
20+
21+
## Feature Request
22+
> $ARGUMENTS
23+
24+
This will guide you through all 4 phases automatically.

0 commit comments

Comments
 (0)