> **Purpose**: This file provides comprehensive context about the Warply Android SDK codebase for AI coding agents (Claude Code, Gemini CLI, Codex, OpenCode, Cline, etc.). It describes architecture, patterns, conventions, and critical rules to follow when working with this project.
---
## 1. Project Overview
-**What**: Warply Android SDK — a loyalty, marketing, and engagement SDK for Android apps. It provides campaigns, coupons, couponsets, push notifications, beacons, location tracking, analytics, and user management.
-**Type**: Android Library (AAR) published to Maven via Gradle.
-**Package namespace**: `ly.warp.sdk`
-**License**: BSD-2-Clause (Warply Ltd.) — all source files must retain the license header.
The project contains a **full embedded copy of Volley** under `io/volley/` with custom modifications. This is used for:
- Legacy microapp data posting (batched requests from DB queue)
- Context retrieval
- Device registration
**⚠️ Do NOT replace or upgrade this Volley fork** — it contains custom request types (`WarplyJsonObjectRequest`, `WarplyJsonArrayRequest`) and batching logic specific to the SDK.
**⚠️ CRITICAL**: Auth tokens and client credentials are stored with **field-level encryption** using `CryptoUtils.encrypt()`/`CryptoUtils.decrypt()`. Always use these methods when reading/writing to the `client` and `auth` tables.
| **CouponList** | Extends ArrayList\<Coupon\> | Typed list of coupons |
**⚠️ JSON Handling**: Models use `org.json.JSONObject`/`JSONArray` — **NOT Gson**. Do not change this pattern. The `optNullableString()` helper must be used for nullable String fields.
-**Callbacks over coroutines** — all async uses `CallbackReceiver<T>`
-**Author attribution**: `Created by Panagiotis Triantafyllou on <date>.`
---
## 11. Critical Rules for AI Agents
### ⚠️ DO NOT:
1.**Do NOT use Gson for model serialization** — all models use `org.json.JSONObject`/`JSONArray`. The `converter-gson` dependency is only for Retrofit response parsing.
2.**Do NOT modify the embedded Volley fork** (`io/volley/`) — it contains customized request handling specific to the SDK's microapp architecture.
3.**Do NOT store tokens in plain text** — always use `CryptoUtils.encrypt()` when writing to the `client` or `auth` DB tables, and `CryptoUtils.decrypt()` when reading.
4.**Do NOT change Activities to AppCompatActivity** unless explicitly required — the SDK uses `android.app.Activity` base class.
5.**Do NOT introduce Kotlin** into the SDK module — it is a pure Java codebase.
6.**Do NOT hard-code server URLs, API keys, or UUIDs** — these come from `warply.properties` via `WarplyProperty`.
7.**Do NOT remove or modify the BSD license headers** from source files.
8.**Do NOT expose sensitive data** (tokens, keys, credentials) in logs — all logging is gated behind `WarpConstants.DEBUG`.
### ✅ DO:
1.**Follow the Parcelable + Serializable pattern** for all new data models.
2.**Use `optNullableString()` helper** for nullable String JSON fields in models.
3.**Use `CallbackReceiver<T>` pattern** for all new async operations.
4.**Use Guava `ListenableFuture`** with `Futures.allAsList()` for parallel API calls in `WarplyManager`.
5.**Post results to main thread** via `new Handler(Looper.getMainLooper()).post(...)` in Futures callbacks.
6.**Implement token refresh retry** (max 3 attempts) for authenticated endpoints.
7.**Use `WarpUtils.renderCustomFont()`** for applying custom fonts to TextViews.
8.**Use `WarpUtils.applyEdgeToEdge()`** for edge-to-edge display in new Activities.
9.**Cache API results** in `WarplyManagerHelper` static fields for UI consumption.
10.**Update `WarpConstants.SDK_VERSION`** and `build.gradle``PUBLISH_VERSION` when making version changes.
---
## 12. Common Tasks Quick Reference
### Adding a new API endpoint:
1. Add Retrofit method to `ApiService.java`
2. Add static method in `WarplyManager.java` with `ListenableFuture` pattern
3. Create/update model in `io/models/`
4. Add cache field in `WarplyManagerHelper.java` if needed
5. Call from Activity/Fragment with `CallbackReceiver<T>`
### Adding a new Activity:
1. Create in `ly.warp.sdk.activities`
2. Extend `android.app.Activity`
3. Register in `warply_android_sdk/src/main/AndroidManifest.xml` with `android:exported="false"` and `android:theme="@style/SDKAppTheme"`
4. Use `WarpUtils.applyEdgeToEdge()` in `onCreate()`
5. Follow `mPrefixed` naming for view fields
### Adding a new data model:
1. Create in `ly.warp.sdk.io.models`
2. Implement `Parcelable, Serializable`
3. Define JSON key constants as `private static final String`
tools:text="Πάρτε τα πακέτα κινητής στη μισή τιμή μόνο αυτό το μήνα. Απεριόριστα λεπτά προς όλα τα δίκτυα, SMS και 50GB δεδομένα υψηλής ταχύτητας. Ισχύει για νέους συνδρομητές και ανανεώσεις συμβολαίων. Δωρεάν ενεργοποίηση και τεχνική υποστήριξη."/>
<stringname="demo_copy_success">Ο κωδικός αντιγράφηκε στο πρόχειρο</string>
<stringname="demo_lorem_ipsum">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</string>