feat: add ESLint and Prettier configuration for code quality
- Added ESLint with TypeScript support and custom rules. - Introduced Prettier for consistent code formatting. - Updated package.json to include lint and format scripts. - Modified db.ts to ensure proper parsing of BIGINT types from PostgreSQL. - Enhanced webRoutes to coerce timestamp fields to numbers and format isDeleted as boolean.
This commit is contained in:
@@ -9,7 +9,7 @@ A collaborative table management Android application built with Jetpack Compose
|
||||
- Add items with values for each field
|
||||
- Beautiful Material 3 design with dynamic colors
|
||||
- Local Room database for offline support
|
||||
- Automatic synchronization with server
|
||||
- Automatic synchronization with server (WebSocket-first with HTTP fallback)
|
||||
- Soft delete support (items can be recovered on server)
|
||||
|
||||
## Architecture
|
||||
@@ -69,7 +69,8 @@ app/src/main/java/com/collabtable/app/
|
||||
- **Jetpack Compose**: Modern declarative UI toolkit
|
||||
- **Material 3**: Latest Material Design guidelines
|
||||
- **Room**: Local SQLite database
|
||||
- **Retrofit**: REST API client
|
||||
- **Retrofit**: REST API client (fallback)
|
||||
- **OkHttp WebSocket**: Real-time sync channel
|
||||
- **Kotlin Coroutines**: Asynchronous programming
|
||||
- **Flow**: Reactive data streams
|
||||
|
||||
@@ -97,12 +98,17 @@ app/src/main/java/com/collabtable/app/
|
||||
|
||||
## Synchronization
|
||||
|
||||
The app includes sync functionality that:
|
||||
- Sends local changes to the server
|
||||
- Receives changes from other clients
|
||||
- Resolves conflicts using timestamps (latest wins)
|
||||
The app uses a WebSocket-first sync strategy with an HTTP fallback:
|
||||
|
||||
To trigger sync, you can call the `SyncRepository.performSync()` method from your code.
|
||||
- WebSocket (`/api/ws`): Sends a `sync` message with local changes and receives deltas plus the new `serverTimestamp`.
|
||||
- HTTP (`POST /api/sync`): Used automatically as a fallback if the WS exchange fails.
|
||||
|
||||
Behavior:
|
||||
- Sends local changes since the last sync and receives server changes since the last known timestamp.
|
||||
- Timestamps are used to resolve conflicts (latest wins).
|
||||
- If the server is protected with `SERVER_PASSWORD`, the app sends `Authorization: Bearer <password>` for both HTTP and WebSocket.
|
||||
|
||||
To trigger sync programmatically, call `SyncRepository.performSync()`.
|
||||
|
||||
## Building for Release
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.devtools.ksp'
|
||||
id 'org.jlleitschuh.gradle.ktlint'
|
||||
id 'io.gitlab.arturbosch.detekt'
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -87,3 +89,16 @@ dependencies {
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
||||
}
|
||||
|
||||
// Ktlint configuration
|
||||
ktlint {
|
||||
android.set(true)
|
||||
ignoreFailures.set(false)
|
||||
outputToConsole.set(true)
|
||||
}
|
||||
|
||||
// Detekt configuration (uses default rules; customize via detekt.yml if needed)
|
||||
detekt {
|
||||
buildUponDefaultConfig = true
|
||||
allRules = false
|
||||
}
|
||||
|
||||
+3
-2
@@ -36,6 +36,7 @@ object WebSocketSyncClient {
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.pingInterval(15, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
private fun buildWebSocketUrl(httpApiBaseUrl: String): String {
|
||||
@@ -127,8 +128,8 @@ object WebSocketSyncClient {
|
||||
|
||||
try {
|
||||
socket = client.newWebSocket(httpRequest, listener)
|
||||
// Wait up to 15s for response
|
||||
val result = withTimeout(15_000) { deferred.await() }
|
||||
// Wait up to 30s for response (WS roundtrip)
|
||||
val result = withTimeout(30_000) { deferred.await() }
|
||||
return@withContext result
|
||||
} catch (e: Exception) {
|
||||
Logger.w("WS", "Falling back to HTTP sync: ${e.message}")
|
||||
|
||||
@@ -4,4 +4,6 @@ plugins {
|
||||
id 'com.android.library' version '8.3.0' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.9.20' apply false
|
||||
id 'com.google.devtools.ksp' version '1.9.20-1.0.14' apply false
|
||||
id 'org.jlleitschuh.gradle.ktlint' version '12.1.0' apply false
|
||||
id 'io.gitlab.arturbosch.detekt' version '1.23.6' apply false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user