Skip to content

Commit 12eb762

Browse files
authored
Merge branch 'main' into remove-onyx-connect-in-Task-p1
2 parents 3c1a7f6 + 099ec26 commit 12eb762

146 files changed

Lines changed: 4526 additions & 486 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.

CLAUDE.md

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# Expensify App
2+
3+
## Repository Overview
4+
5+
### Technology Stack
6+
- **Framework**: React Native
7+
- **Language**: TypeScript
8+
- **State Management**: React Native Onyx
9+
- **Navigation**: React Navigation
10+
- **Platforms**: iOS, Android, Web, Desktop (Electron)
11+
12+
## HybridApp Architecture (Critical Context)
13+
14+
**IMPORTANT**: The mobile application is built from the Mobile-Expensify submodule, not directly from the App repository.
15+
**IMPORTANT**: NewDot refers to the new Expensify App, OldDot or Expensify Classic refers to our Old expensify app and website
16+
17+
### Key Integration Points
18+
- App (NewDot) and Mobile-Expensify (OldDot) are combined into a single mobile application
19+
- The HybridApp module (`@expensify/react-native-hybrid-app`) manages transitions between OldDot and NewDot
20+
- Build process merges dotenv configurations from both repositories
21+
- Environment variables from Mobile-Expensify take precedence over App variables
22+
- Mobile builds **must** be initiated from the Mobile-Expensify directory
23+
24+
### Build Modes
25+
- **Standalone**: Pure NewDot application (web/desktop)
26+
- **HybridApp**: Combined OldDot + NewDot (mobile apps)
27+
- Controlled via `STANDALONE_NEW_DOT` environment variable
28+
29+
## Core Architecture & Structure
30+
31+
### Entry Points
32+
- `src/App.tsx`: Main application component with provider hierarchy
33+
- `src/Expensify.tsx`: Core application logic and initialization
34+
- `src/HybridAppHandler.tsx`: Manages HybridApp transitions and authentication
35+
- `index.js`: React Native entry point
36+
37+
### Provider Architecture
38+
The application uses a nested provider structure for context management:
39+
1. **SplashScreenStateContextProvider**: Manages splash screen visibility
40+
2. **InitialURLContextProvider**: Handles deep linking
41+
3. **ThemeProvider**: Theme management
42+
4. **LocaleContextProvider**: Internationalization
43+
5. **OnyxListItemProvider**: Data layer provider
44+
6. **SafeAreaProvider**: Device safe areas
45+
7. **PopoverContextProvider**: Global popover state
46+
8. **KeyboardProvider**: Keyboard state management
47+
48+
### Data Layer
49+
- **Onyx**: Custom data persistence layer for offline-first functionality
50+
- **ONYXKEYS.ts**: Centralized key definitions for data store
51+
- Supports optimistic updates and conflict resolution
52+
53+
## Key Features & Modules
54+
55+
### Core Functionality
56+
1. **Expense Management**
57+
- Receipt scanning and SmartScan
58+
- Expense creation and editing
59+
- Distance tracking
60+
- Per diem support
61+
- Split expenses
62+
63+
2. **Reporting**
64+
- Report creation and submission
65+
- Approval workflows
66+
- Report fields and custom attributes
67+
- Bulk operations
68+
69+
3. **Workspace/Policy Management**
70+
- Policy creation and configuration
71+
- Member management
72+
- Categories, tags, and tax rates
73+
- Accounting integration settings
74+
- Approval workflows
75+
76+
4. **Travel**
77+
- Trip management
78+
- Travel booking integration
79+
- Travel policy enforcement
80+
81+
5. **Search & Filtering**
82+
- Advanced search with filters
83+
- Saved searches
84+
- Search parser (Peggy-based)
85+
86+
6. **Payment & Cards**
87+
- Expensify Card management
88+
- Bank account connections (Plaid)
89+
- Payment methods
90+
- Company cards integration
91+
- Wallet functionality
92+
93+
7. **Accounting Integrations**
94+
- QuickBooks Online
95+
- Xero
96+
- NetSuite
97+
- Sage Intacct
98+
- QuickBooks Desktop
99+
- Generic accounting connections
100+
101+
8. **Communication**
102+
- Chat functionality
103+
- Task management
104+
- Mentions and notifications
105+
- Thread organization
106+
107+
9. **Invoice Management**
108+
- Invoice creation and sending
109+
- Invoice rooms
110+
111+
## Navigation & Routing
112+
113+
### Structure
114+
- `src/SCREENS.ts`: Screen name constants
115+
- `src/ROUTES.ts`: Route definitions and builders
116+
- `src/NAVIGATORS.ts`: Navigator configuration
117+
118+
### Key Navigators
119+
- **ProtectedScreens**: Authenticated app screens
120+
- **PublicScreens**: Login and onboarding screens
121+
- **RHP (Right Hand Panel/Pane)**: Settings and details panel
122+
- **Central Pane**: Main content area
123+
- **LHN (Left Hand Navigation)**: Report list and navigation
124+
- **RHP**: Contextual panels and settings
125+
126+
## State Management
127+
128+
### Onyx Keys Organization
129+
- **Session**: Authentication and user session
130+
- **Personal Details**: User profiles and preferences
131+
- **Reports**: Chat and expense reports
132+
- **Transactions**: Expense transactions
133+
- **Policy**: Workspace configuration
134+
- **Forms**: Form state management
135+
136+
### Action Modules (`src/libs/actions/`)
137+
Major action categories:
138+
- `App.ts`: Application lifecycle
139+
- `IOU.ts`: Money requests and expenses
140+
- `Report.ts`: Report management
141+
- `Policy/`: Workspace operations
142+
- `User.ts`: User account operations
143+
- `Session.ts`: Authentication
144+
- `Search.ts`: Search operations
145+
- `Travel.ts`: Travel features
146+
147+
## Build & Deployment
148+
149+
### CI/CD Workflows
150+
Key GitHub Actions workflows:
151+
- `deploy.yml`: Production deployment
152+
- `preDeploy.yml`: Staging deployment
153+
- `testBuild.yml`: PR test builds
154+
- `test.yml`: Unit tests
155+
- `typecheck.yml`: TypeScript validation
156+
- `lint.yml`: Code quality checks
157+
- `e2ePerformanceTests.yml`: Performance testing
158+
159+
## Related Repositories
160+
161+
### Mobile-Expensify (Submodule)
162+
- **Path**: `App/Mobile-Expensify/`
163+
- **Purpose**: Legacy OldDot application and mobile build source
164+
- **Critical**: All mobile builds originate from this directory
165+
- Contains platform-specific code for iOS and Android
166+
- Manages the HybridApp integration layer
167+
168+
### expensify-common
169+
- **Purpose**: Shared libraries and utilities
170+
- Contains common validation, parsing, and utility functions
171+
- Used across multiple Expensify repositories
172+
173+
## Development Practices
174+
175+
### Code Quality
176+
- **TypeScript**: Strict mode enabled
177+
- **ESLint**: Linter
178+
- **Prettier**: Automatic formatting
179+
- **Patch Management**: patch-package for dependency fixes
180+
181+
### Testing
182+
- **Unit Tests**: Jest with React Native Testing Library
183+
- **E2E Tests**: Custom test runner
184+
- **Performance Tests**: Reassure framework
185+
186+
## Special Considerations
187+
188+
### Offline-First Architecture
189+
- All features work offline
190+
- Optimistic updates with rollback
191+
- Queue-based request handling
192+
- Conflict resolution strategies
193+
194+
### Mobile-Specific Notes
195+
- Push notifications via Airship
196+
- Mapbox integration for location features
197+
- Camera and gallery access
198+
199+
### Security
200+
- Content Security Policy enforcement
201+
- Two-factor authentication support
202+
203+
## Documentation Resources
204+
205+
### Help Documentation
206+
- **NewDot Help**: https://help.expensify.com/new-expensify/hubs/
207+
- **OldDot/Expensify Classic Help**: https://help.expensify.com/expensify-classic/hubs/
208+
209+
## Development Setup Requirements
210+
211+
## Command Reference
212+
213+
### Common Tasks
214+
```bash
215+
# Install dependencies
216+
npm install
217+
218+
# Clean build artifacts
219+
npm run clean
220+
221+
# Type checking
222+
npm run typecheck
223+
224+
# Linting
225+
npm run lint
226+
227+
# Testing
228+
npm run test
229+
```
230+
231+
### Platform Builds
232+
```bash
233+
# iOS build
234+
npm run ios
235+
236+
# Android build
237+
npm run android
238+
239+
# Desktop build
240+
npm run desktop
241+
242+
# Web build
243+
npm run web
244+
```
245+
246+
## Architecture Decisions
247+
248+
### React Native New Architecture
249+
- Fabric renderer enabled
250+
- TurboModules for native module integration
251+
- Hermes JavaScript engine
252+
253+
### State Management Choice
254+
- Custom Onyx library for offline-first capabilities
255+
- Optimistic updates as default pattern
256+
- Centralized action layer for API calls
257+
- Direct key-value storage with automatic persistence
258+
259+
### Navigation Strategy
260+
- React Navigation for cross-platform consistency
261+
- Custom navigation state management
262+
- Deep linking support
263+
264+
## Known Integration Points
265+
266+
### With Mobile-Expensify
267+
- Session sharing via HybridApp module
268+
- Navigation handoff between apps
269+
- Shared authentication state
270+
- Environment variable merging
271+
272+
### With Backend Services
273+
- RESTful API communication
274+
- WebSocket connections via Pusher
275+
- Real-time synchronization

Mobile-Expensify

__mocks__/react-native-onyx.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type ConnectionCallbackParams<TKey extends OnyxKey> = Parameters<ConnectionCallb
2222

2323
const reactNativeOnyxMock: ReactNativeOnyxMock = {
2424
...Onyx,
25-
connect: <TKey extends OnyxKey>(mapping: ConnectOptions<TKey>) => {
25+
connectWithoutView: <TKey extends OnyxKey>(mapping: ConnectOptions<TKey>) => {
2626
const callback = (...params: ConnectionCallbackParams<TKey>) => {
2727
if (connectCallbackDelay > 0) {
2828
setTimeout(() => {
@@ -32,7 +32,7 @@ const reactNativeOnyxMock: ReactNativeOnyxMock = {
3232
(mapping.callback as (...args: ConnectionCallbackParams<TKey>) => void)?.(...params);
3333
}
3434
};
35-
return Onyx.connect({
35+
return Onyx.connectWithoutView({
3636
...mapping,
3737
callback,
3838
});
@@ -41,4 +41,5 @@ const reactNativeOnyxMock: ReactNativeOnyxMock = {
4141
};
4242

4343
export default reactNativeOnyxMock;
44+
// eslint-disable-next-line
4445
export {withOnyx, useOnyx};

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ android {
114114
minSdkVersion rootProject.ext.minSdkVersion
115115
targetSdkVersion rootProject.ext.targetSdkVersion
116116
multiDexEnabled rootProject.ext.multiDexEnabled
117-
versionCode 1009019501
118-
versionName "9.1.95-1"
117+
versionCode 1009019600
118+
versionName "9.1.96-0"
119119
// Supported language variants must be declared here to avoid from being removed during the compilation.
120120
// This also helps us to not include unnecessary language variants in the APK.
121121
resConfigs "en", "es"

cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
"formatjs",
240240
"Français",
241241
"Frederico",
242+
"freetext",
242243
"frontpart",
243244
"fullstory",
244245
"FWTV",

docs/articles/new-expensify/workspaces/Configure-Per-Diem-in-a-workspace.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ Both options are found in the **three-dot menu** at the top-right corner of the
3838

3939
---
4040

41+
# Per Diem Rate Templates
42+
43+
Below are some example templates to reference:
44+
45+
- [Germany rates]({{site.url}}/assets/Files/Germany-per-diem.csv)
46+
- [Sweden rates]({{site.url}}/assets/Files/Sweden-per-diem.csv)
47+
- [Finland rates]({{site.url}}/assets/Files/Finland-per-diem.csv)
48+
- [South Africa single rates]({{site.url}}/assets/Files/South-Africa-per-diem.csv)
49+
50+
---
51+
4152
# Edit or Delete Per Diem Rates
4253

4354
Each rate is listed as a line item. You can:

ios/NewExpensify/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<key>CFBundlePackageType</key>
2424
<string>APPL</string>
2525
<key>CFBundleShortVersionString</key>
26-
<string>9.1.95</string>
26+
<string>9.1.96</string>
2727
<key>CFBundleSignature</key>
2828
<string>????</string>
2929
<key>CFBundleURLTypes</key>
@@ -44,7 +44,7 @@
4444
</dict>
4545
</array>
4646
<key>CFBundleVersion</key>
47-
<string>9.1.95.1</string>
47+
<string>9.1.96.0</string>
4848
<key>FullStory</key>
4949
<dict>
5050
<key>OrgId</key>

ios/NotificationServiceExtension/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<key>CFBundleName</key>
1212
<string>$(PRODUCT_NAME)</string>
1313
<key>CFBundleShortVersionString</key>
14-
<string>9.1.95</string>
14+
<string>9.1.96</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.1.95.1</string>
16+
<string>9.1.96.0</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionPointIdentifier</key>

ios/ShareViewController/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<key>CFBundleName</key>
1212
<string>$(PRODUCT_NAME)</string>
1313
<key>CFBundleShortVersionString</key>
14-
<string>9.1.95</string>
14+
<string>9.1.96</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.1.95.1</string>
16+
<string>9.1.96.0</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionAttributes</key>

0 commit comments

Comments
 (0)