Skip to content

Commit 7c84709

Browse files
committed
Initial commit
0 parents  commit 7c84709

655 files changed

Lines changed: 122524 additions & 0 deletions

File tree

Some content is hidden

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

.editorconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
root = true
2+
3+
[*.{kt,kts}]
4+
# Allow inline comments in argument/parameter lists (used across decoders/parsers)
5+
ktlint_standard_discouraged-comment-location = disabled
6+
ktlint_standard_if-else-wrapping = disabled
7+
ktlint_standard_wrapping = disabled
8+
ktlint_standard_argument-list-wrapping = disabled
9+
ktlint_standard_parameter-list-wrapping = disabled
10+
ktlint_standard_trailing-comma-on-call-site = disabled
11+
ktlint_standard_trailing-comma-on-declaration-site = disabled
12+
ktlint_standard_no-consecutive-comments = disabled
13+
ktlint_standard_function-naming = disabled
14+
ktlint_standard_no-wildcard-imports = disabled
15+
ktlint_standard_property-naming = disabled
16+
ktlint_standard_max-line-length = disabled
17+
ktlint_standard_no-empty-file = disabled

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# https://help.github.com/articles/dealing-with-line-endings/
3+
#
4+
# Linux start script should use lf
5+
/gradlew text eol=lf
6+
7+
# These are Windows script files and should use crlf
8+
*.bat text eol=crlf
9+
10+
# Binary files should be left untouched
11+
*.jar binary
12+

.github/workflows/gitleaks.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Secret Scan
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
workflow_dispatch:
9+
schedule:
10+
- cron: "0 4 * * 1"
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
gitleaks:
17+
name: gitleaks
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout full history
21+
uses: actions/checkout@v7
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Scan secrets
26+
uses: gitleaks/gitleaks-action@v3
27+
env:
28+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Ignore Gradle project-specific cache directory
2+
.gradle
3+
4+
# Ignore Gradle build output directory
5+
build
6+
local.properties
7+
.idea/
8+
*.iml
9+
.gradle_android
10+
11+
# macOS
12+
.DS_Store
13+
.AppleDouble
14+
.LSOverride
15+
16+
# Temporary files
17+
*.tmp
18+
*.bak
19+
*~
20+
.tmp/
21+
22+
# Android Studio
23+
*.apk
24+
*.ap_
25+
*.dex
26+
captures/
27+
db_dump/
28+
datasets/
29+
db_dump/
30+
matching_engine/
31+
32+
*.db
33+
*.db-shm
34+
*.db-wal
35+
verification_logs*.txt
36+
37+
# Secret scanning reports
38+
gitleaks-report.*
39+
*.sarif

.gitleaks.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
title = "BlueEye Tracker gitleaks config"
2+
3+
[extend]
4+
useDefault = true
5+
6+
[allowlist]
7+
description = "Repository-local non-secret paths"
8+
paths = [
9+
'''(^|/)\.gradle/''',
10+
'''(^|/)\.idea/''',
11+
'''(^|/)build/''',
12+
'''(^|/)app/build/''',
13+
'''(^|/)core/[^/]+/build/''',
14+
'''(^|/)feature/[^/]+/build/''',
15+
'''(?i)\.(png|jpe?g|webp|gif|svg)$''',
16+
]

.vscode/extensions.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"recommendations": [
3+
"fwcd.kotlin",
4+
"mathiasfrohlich.Kotlin",
5+
"vscjava.vscode-gradle",
6+
"vscjava.vscode-java-pack"
7+
]
8+
}

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"java.configuration.updateBuildConfiguration": "automatic"
3+
}

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# BlueEye Tracker
2+
3+
Android app for observing nearby Bluetooth/BLE devices, keeping a watchlist, and showing alerts when selected devices reappear.
4+
5+
This repository is a Kotlin / Jetpack Compose Android project. The current code is usable for development, but detection confidence and architecture still need hardening before the app should present strong claims to the user.
6+
7+
## Current Scope
8+
9+
- Passive BLE and Bluetooth observation.
10+
- Radar screen with currently observed devices.
11+
- Device details, parsed metadata, RSSI history, and raw data views.
12+
- Watchlist alerts for known/reappearing devices.
13+
- Foreground scanning service.
14+
- Decoder library for common BLE ecosystems and sensors.
15+
16+
The app must not claim that a person, agency, or intent was identified from Bluetooth alone. It can only show evidence, confidence, and reasons.
17+
18+
## Project Shape
19+
20+
- `app`: single Android app module, `MainActivity`, Navigation Compose, Hilt module wiring.
21+
- `core:model`: shared domain-ish models.
22+
- `core:domain`: repository contracts and use cases.
23+
- `core:data`: Room, Bluetooth scanning, scanner service, classification, tracking/session logic.
24+
- `core:decoders`: BLE manufacturer/service data decoders.
25+
- `core:ui`: Compose theme, design tokens, shared UI utilities.
26+
- `feature:*`: Compose screens and ViewModels.
27+
28+
Known architecture gaps are documented in [docs/ARCHITECTURE_CURRENT.md](docs/ARCHITECTURE_CURRENT.md).
29+
30+
## Quality Gate
31+
32+
Use Java 17:
33+
34+
```bash
35+
export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
36+
./gradlew qualityCheck
37+
./gradlew :app:assembleDebug
38+
```
39+
40+
Secret scanning is configured in GitHub Actions. To run it locally:
41+
42+
```bash
43+
gitleaks git --config .gitleaks.toml --redact --verbose
44+
```
45+
46+
Details, current exceptions, and baseline policy are in [docs/QUALITY_GATE.md](docs/QUALITY_GATE.md).
47+
48+
## Documentation
49+
50+
- [Product goal](docs/PRODUCT_GOAL.md)
51+
- [Current architecture](docs/ARCHITECTURE_CURRENT.md)
52+
- [Pipeline audit](docs/PIPELINE_AUDIT.md)
53+
- [Quality gate](docs/QUALITY_GATE.md)
54+
- [Detection confidence](docs/DETECTION_CONFIDENCE.md)
55+
- [Evidence model](docs/EVIDENCE_MODEL.md)
56+
57+
## Git Workflow
58+
59+
Work directly on `main`. Do not create new branches unless the user explicitly asks for it.

agents.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# ANDROID MASTERPIECE - SYSTEM INSTRUCTIONS
2+
3+
## ROLE
4+
You are a Lead Android Architect and Google Developer Expert. Your goal is to maintain the project in the **"Modern Android Development (MAD) 2025"** standard.
5+
The project has undergone a complete migration to **Jetpack Compose** and **Clean Architecture**.
6+
There is ZERO tolerance for technical debt, XML layouts, Fragments, or legacy patterns.
7+
8+
## 1. TECH STACK (HARD CONSTRAINTS)
9+
* **Language:** 100% Kotlin.
10+
* **UI Framework:** 100% Jetpack Compose (Material 3).
11+
* **FORBIDDEN:** XML Layouts, Drawables (use Vector Assets/Compose), Styles.xml, ViewBinding, DataBinding.
12+
* **Architecture:** Single Activity + Navigation Compose.
13+
* **FORBIDDEN:** Fragments, FragmentManager, Multiple Activities.
14+
* **Dependency Injection:** Hilt (Dagger).
15+
* **Concurrency:** Coroutines + Flow (StateFlow/SharedFlow).
16+
* **FORBIDDEN:** AsyncTask, Thread, RxJava, LiveData.
17+
* **Build System:** Gradle Kotlin DSL (`build.gradle.kts`) + Version Catalogs (`libs.versions.toml`).
18+
* **Serialization:** Kotlin Serialization (JSON).
19+
* **FORBIDDEN:** GSON, Jackson, Moshi (unless external API requires, but map to Domain immediately).
20+
21+
## 2. THE HOLY RULES OF ARCHITECTURE
22+
23+
### A. Project Structure (Feature-First)
24+
Code is organized by feature: `com.app.name.features.[feature_name]`.
25+
Each feature MUST follow strict layering:
26+
1. **Domain Layer:**
27+
* Pure Kotlin `data classes` (Entities).
28+
* Repository Interfaces.
29+
* Use Cases (Interactors).
30+
* Return types: Use `Result<T>` to encapsulate success/failure for ALL methods. Do NOT throw exceptions.
31+
* **RULE:** No Android SDK dependencies (except `@Parcelize` if absolutely necessary).
32+
2. **Data Layer:**
33+
* Repository Implementations.
34+
* DTOs (Data Transfer Objects).
35+
* Data Sources (Room, Retrofit, Bluetooth/BLE Managers).
36+
3. **Presentation Layer:**
37+
* Screens (Composables).
38+
* ViewModels.
39+
* UI State Models.
40+
41+
### B. State Management (Unidirectional Data Flow)
42+
* **Single Source of Truth:** The UI is stateless. It only renders the state provided by the ViewModel.
43+
* **StateFlow:** ViewModel exposes `val uiState: StateFlow<MyScreenUiState>`.
44+
* **Consumption:** Composables use `val state by viewModel.uiState.collectAsStateWithLifecycle()`.
45+
* **Events:** User actions are passed up to the ViewModel via lambda callbacks or method calls (e.g., `viewModel.onEvent(MyEvent.Refresh)`).
46+
47+
### C. Hardware & Core Logic (IoT/Bluetooth)
48+
* **Isolation:** All Bluetooth/BLE logic resides in `core/data` (e.g., `BluetoothDataSource`).
49+
* **No Leaks:** Never expose `BluetoothGatt`, `BluetoothDevice` or raw bytes to the UI layer.
50+
* **Mapping:** Mandatory `toDomain()` extension functions for all Data Entities/DTOs. Never leak Data Layer models (Room @Entity, Retrofit DTO) into the Domain or Presentation.
51+
52+
### D. Navigation (Type-Safe)
53+
* Use **Jetpack Navigation Compose** with **Kotlin Serialization**.
54+
* Routes are defined as `@Serializable` data classes or objects.
55+
* **FORBIDDEN:** Hardcoded string routes (e.g., `"details/{id}"`) or passing complex objects via Bundles.
56+
* Use `hiltViewModel()` to inject ViewModels scoped to the navigation graph.
57+
58+
### E. Theming & Design System (3-Layer Architecture)
59+
The project (`io.blueeye.core.ui.theme`) uses a strict 3-layer styling architecture. You must adhere to this hierarchy:
60+
61+
1. **Layer 1: Fundamental (Primitives)**
62+
* **Files:** `core/ui/theme/Color.kt`, `Type.kt`.
63+
* **RULE (LOCKDOWN):** All color primitives (e.g., `val BlueEyePrimary = Color(...)`) MUST be marked `internal` or `private`.
64+
* **PROHIBITED:** Never expose raw colors as `public`. Never use `R.color.*` resources.
65+
66+
2. **Layer 2: Material 3 (Standard Wrapper)**
67+
* **File:** `Theme.kt`.
68+
* **Purpose:** Map primitives to standard M3 roles (`colorScheme.primary`, `colorScheme.surface`).
69+
* **Usage:** Use these for generic UI components (Standard Buttons, Cards, Backgrounds).
70+
71+
3. **Layer 3: Extended "Professional" (Domain Specific)**
72+
* **File:** `Theme.kt` (via `CompositionLocal`).
73+
* **Purpose:** Handling domain-specific states (Tracker/Radar/IoT) that standard Material Design does not cover.
74+
* **Content:** `MaterialTheme.extendedColors` exposing semantic roles (e.g., `.dangerous`, `.safe`, `.suspicious`).
75+
* **Usage:** ALWAYS use `MaterialTheme.extendedColors.[role]` for domain logic.
76+
* **Implementation:** Must use `staticCompositionLocalOf { error("...") }` to ensure safety.
77+
78+
**VERIFICATION PROTOCOL:**
79+
* If you see `Color(0xFF...)` in a Feature Module -> **REJECT**.
80+
* If you see `R.color.my_color` -> **REJECT**.
81+
* If `Color.kt` contains `public val` -> **FIX to `internal`**.
82+
83+
## 3. CODING STANDARDS & QUALITY
84+
* **Previews:** Every Composable (Screen or component) MUST have a `@Preview` annotation for visual testing using `PreviewParameterProvider` if needed.
85+
* **Theming:** ALWAYS use `MaterialTheme` tokens (Layer 2 or Layer 3).
86+
* **Dimensions:** All dimensions MUST be defined in `Dimens.kt` using `dp` or `sp` tokens.
87+
* **Error Handling:** Errors are part of the UI State (e.g., `sealed interface UiState { data class Error(val msg: String) ... }`). Do not rely solely on Logs.
88+
* **Cleanup:** When modifying code, always remove unused imports, commented-out code, and legacy resources.
89+
90+
## 4. AGENT WORKFLOW (HOW TO ACT)
91+
* **Git Workflow:** Work directly on `main` for this repository. Do NOT create `codex/*`, feature, or temporary branches unless the user explicitly requests a separate branch in the current task. When asked to publish work, merge the current work into `main`, push `main`, and remove temporary branches from both local git and GitHub.
92+
93+
1. **Analyze:** Before writing code, verify the file type. If you are tempted to create an XML file -> **STOP**.
94+
2. **Design First:**
95+
* Define the **Domain Model** (Entity) & Result types.
96+
* Define the **UI State** (`data class` with immutability).
97+
* Define the **ViewModel** public API.
98+
* **Theme Strategy:** Determine if you need Layer 2 (Standard M3) or Layer 3 (Extended Domain Colors).
99+
3. **Implement:** Write the Composable last.
100+
4. **Verify:** Check imports. If you see `android.view.View`, `R.color.*`, or hardcoded `Color(0xFF...)`, you have failed. Fix it immediately.

app/build.gradle.kts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
plugins {
2+
alias(libs.plugins.android.application)
3+
alias(libs.plugins.kotlin.android)
4+
alias(libs.plugins.kotlin.kapt)
5+
alias(libs.plugins.hilt)
6+
alias(libs.plugins.kotlin.serialization)
7+
}
8+
9+
android {
10+
namespace = "io.blueeye"
11+
compileSdk = 34
12+
13+
defaultConfig {
14+
applicationId = "io.blueeye"
15+
minSdk = 26 // Zgodnie z README dla BLE 5.0
16+
targetSdk = 33
17+
versionCode = 1
18+
versionName = "1.0"
19+
20+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
21+
}
22+
23+
buildTypes {
24+
release {
25+
isMinifyEnabled = false
26+
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
27+
}
28+
}
29+
compileOptions {
30+
sourceCompatibility = JavaVersion.VERSION_17
31+
targetCompatibility = JavaVersion.VERSION_17
32+
}
33+
kotlinOptions {
34+
jvmTarget = "17"
35+
}
36+
buildFeatures {
37+
compose = true
38+
}
39+
composeOptions {
40+
kotlinCompilerExtensionVersion = "1.5.8"
41+
}
42+
}
43+
44+
dependencies {
45+
// Modules
46+
implementation(project(":core:model"))
47+
implementation(project(":core:decoders"))
48+
implementation(project(":core:data"))
49+
implementation(project(":feature:radar"))
50+
implementation(project(":feature:details"))
51+
implementation(project(":feature:settings"))
52+
implementation(project(":feature:watchlist"))
53+
54+
implementation(project(":core:ui"))
55+
56+
// Navigation
57+
58+
// Compose
59+
implementation(platform(libs.androidx.compose.bom))
60+
implementation(libs.androidx.ui)
61+
implementation(libs.androidx.ui.graphics)
62+
implementation(libs.androidx.ui.tooling.preview)
63+
implementation(libs.androidx.material3)
64+
implementation(libs.androidx.activity.compose)
65+
implementation(libs.androidx.navigation.compose)
66+
implementation(libs.androidx.hilt.navigation.compose)
67+
implementation(libs.androidx.lifecycle.runtime.compose)
68+
debugImplementation(libs.androidx.ui.tooling)
69+
debugImplementation(libs.androidx.ui.test.manifest)
70+
71+
// Room Database
72+
implementation(libs.androidx.room.runtime)
73+
implementation(libs.androidx.room.ktx)
74+
kapt(libs.androidx.room.compiler)
75+
76+
// Hilt Dependency Injection
77+
implementation(libs.hilt.android)
78+
kapt(libs.hilt.compiler)
79+
80+
// Coroutines
81+
implementation(libs.kotlinx.coroutines.android)
82+
83+
// DataStore (Preferences)
84+
implementation(libs.androidx.datastore.preferences)
85+
86+
// Kotlinx Serialization
87+
implementation(libs.kotlinx.serialization.json)
88+
89+
// Testing
90+
testImplementation(libs.junit)
91+
testImplementation(libs.mockito.core)
92+
testImplementation(libs.mockito.inline)
93+
testImplementation(libs.mockito.kotlin)
94+
testImplementation(libs.kotlinx.coroutines.test)
95+
androidTestImplementation(libs.androidx.test.ext.junit)
96+
androidTestImplementation(libs.androidx.test.espresso.core)
97+
androidTestImplementation(libs.mockito.android)
98+
}

0 commit comments

Comments
 (0)