Skip to content

Commit dcd3205

Browse files
authored
Merge pull request #1 from rubyad/feature/mobile-phone-verification
fix: login verification + db connection health + migration docs
2 parents 3f756eb + 00ccb35 commit dcd3205

28 files changed

Lines changed: 6316 additions & 11 deletions

assets/js/app.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { TwitterWidgets } from "./twitter_widgets.js";
3838
import { HomeHooks, ModalHooks, DropdownHooks, SearchHooks, ThirdwebLogin, ThirdwebWallet } from "./home_hooks.js";
3939
import { TimeTracker } from "./time_tracker.js";
4040
import { EngagementTracker } from "./engagement_tracker.js";
41+
import { PhoneNumberFormatter } from "./phone_number_formatter.js";
4142
import { BannerUpload } from "./banner_upload.js";
4243
import { BannerDrag } from "./banner_drag.js";
4344
import { TextBlockDrag, TextBlockDragResize, ButtonDrag, AdminControlsDrag } from "./text_block_drag.js";
@@ -312,7 +313,7 @@ const liveSocket = new LiveSocket("/live", Socket, {
312313
pending_claims: pendingClaims.length > 0 ? pendingClaims : null
313314
};
314315
},
315-
hooks: { TipTapEditor, FeaturedImageUpload, HubLogoUpload, HubLogoFormUpload, TwitterWidgets, HomeHooks, ModalHooks, DropdownHooks, SearchHooks, ThirdwebLogin, ThirdwebWallet, TagInput, Autocomplete, CopyToClipboard, ClaimCleanup, InfiniteScroll, TimeTracker, EngagementTracker, BannerUpload, BannerDrag, TextBlockDrag, TextBlockDragResize, ButtonDrag, AdminControlsDrag, ProductImageUpload, TokenInput, ProductDescriptionEditor, ArtistImageUpload, CoinFlip, BuxBoosterOnchain, DepositBuxInput, VideoWatchTracker, FingerprintHook },
316+
hooks: { TipTapEditor, FeaturedImageUpload, HubLogoUpload, HubLogoFormUpload, TwitterWidgets, HomeHooks, ModalHooks, DropdownHooks, SearchHooks, ThirdwebLogin, ThirdwebWallet, TagInput, Autocomplete, CopyToClipboard, ClaimCleanup, InfiniteScroll, TimeTracker, EngagementTracker, PhoneNumberFormatter, BannerUpload, BannerDrag, TextBlockDrag, TextBlockDragResize, ButtonDrag, AdminControlsDrag, ProductImageUpload, TokenInput, ProductDescriptionEditor, ArtistImageUpload, CoinFlip, BuxBoosterOnchain, DepositBuxInput, VideoWatchTracker, FingerprintHook },
316317
});
317318

318319
// connect if there are any LiveViews on the page

assets/js/fingerprint_hook.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export const FingerprintHook = {
44
async mounted() {
55
console.log('FingerprintHook mounted');
66

7+
// Store this hook instance globally so ThirdwebLogin can access it
8+
window.FingerprintHookInstance = this;
9+
710
// Check if we already have a fingerprint in localStorage from a previous session
811
const cachedFingerprint = localStorage.getItem('fp_visitor_id');
912
const cachedConfidence = localStorage.getItem('fp_confidence');
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Real-time phone number formatting as user types
2+
3+
export const PhoneNumberFormatter = {
4+
mounted() {
5+
this.input = this.el;
6+
7+
// Add input listener for formatting
8+
this.input.addEventListener('input', (e) => {
9+
this.formatPhoneNumber(e);
10+
});
11+
12+
// Add paste listener
13+
this.input.addEventListener('paste', (e) => {
14+
setTimeout(() => this.formatPhoneNumber(e), 10);
15+
});
16+
},
17+
18+
formatPhoneNumber(e) {
19+
let value = this.input.value;
20+
21+
// Remove all non-digit characters except +
22+
let cleaned = value.replace(/[^\d+]/g, '');
23+
24+
// If starts with +, preserve it and format intelligently
25+
if (cleaned.startsWith('+')) {
26+
// Just add space after country code if user is typing
27+
// Keep it simple - server will validate
28+
return;
29+
}
30+
31+
// If starts with 1 and has more digits, format as US: +1 (XXX) XXX-XXXX
32+
if (cleaned.startsWith('1') && cleaned.length > 1) {
33+
let digits = cleaned.substring(1); // Remove the leading 1
34+
let formatted = '+1';
35+
36+
if (digits.length > 6) {
37+
formatted = `+1 (${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
38+
} else if (digits.length > 3) {
39+
formatted = `+1 (${digits.slice(0, 3)}) ${digits.slice(3)}`;
40+
} else if (digits.length > 0) {
41+
formatted = `+1 ${digits}`;
42+
}
43+
44+
this.input.value = formatted;
45+
return;
46+
}
47+
48+
// For other numbers starting with digits (not 1), add + and space
49+
if (cleaned.length > 0) {
50+
this.input.value = '+' + cleaned;
51+
}
52+
},
53+
54+
destroyed() {
55+
// Cleanup if needed
56+
}
57+
};

claude.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,3 +2300,43 @@ The `ratePerSecond` is stored in wei (e.g., `1.062454e18` for Aurora). Multiplyi
23002300
- Updated top box links to use this new function
23012301

23022302
**Documentation**: See [high-rollers-nfts/docs/nft_revenues.md](high-rollers-nfts/docs/nft_revenues.md) for complete implementation plan.
2303+
2304+
---
2305+
2306+
## Known Issues
2307+
2308+
### Claude API Error: "tool_use ids must be unique"
2309+
2310+
**Error**: When using Read or Grep tools, the API returns `{"type":"error","error":{"type":"invalid_request_error","message":"tool_use ids must be unique"}}`
2311+
2312+
**When It Happens**:
2313+
- Even at the start of fresh conversations
2314+
- Across different Claude models (Sonnet, Opus)
2315+
- Consistently reproducible when trying to read files directly
2316+
- Appears to be a platform-level issue with tool ID generation
2317+
2318+
**Workaround**: Use the Task tool with general-purpose agent to read files instead of direct Read/Grep calls:
2319+
```
2320+
Instead of:
2321+
Read file directly → API error
2322+
2323+
Use:
2324+
Task tool → spawns separate agent context → agent uses Read/Grep → succeeds
2325+
```
2326+
2327+
**Why It Works**: Task agents run in a separate context with their own tool ID space, avoiding ID collisions that cause the error.
2328+
2329+
**Recommendation**:
2330+
- When encountering "tool_use ids must be unique" error, switch to using Task tool for file reading operations
2331+
- Task tool is reliable for reading, grepping, and analyzing files
2332+
- This is a temporary workaround until the underlying API issue is resolved
2333+
- Do NOT waste time debugging tool call syntax - it's not a code issue, it's a platform issue
2334+
2335+
**Example**:
2336+
```
2337+
User: "Read the config file"
2338+
2339+
Instead of calling Read tool directly (which may error):
2340+
Use Task tool: "Read /path/to/config.exs and summarize the configuration"
2341+
The spawned agent will successfully read and return the contents
2342+
```

config/runtime.exs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ config :blockster_v2,
4646
if(config_env() == :prod,
4747
do: "https://blockster-v2.fly.dev",
4848
else: "http://localhost:4000"
49-
)
49+
),
50+
twilio_account_sid: System.get_env("TWILIO_ACCOUNT_SID"),
51+
twilio_auth_token: System.get_env("TWILIO_AUTH_TOKEN"),
52+
twilio_verify_service_sid: System.get_env("TWILIO_VERIFY_SERVICE_SID")
5053

5154
# Mnesia configuration
5255
# In production, Mnesia data is stored in /data/mnesia/blockster (Fly.io persistent volume)
@@ -98,6 +101,13 @@ if config_env() == :prod do
98101
# ssl: true,
99102
url: database_url,
100103
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
104+
# Connection pool health settings - help detect and recover from connection issues
105+
queue_target: 50,
106+
queue_interval: 1000,
107+
# Timeout settings to detect dead connections faster
108+
timeout: 15000,
109+
connect_timeout: 15000,
110+
handshake_timeout: 15000,
101111
# For machines with several cores, consider starting multiple pools of `pool_size`
102112
# pool_count: 4,
103113
socket_options: maybe_ipv6

config/test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ config :phoenix_live_view,
3838

3939
# Disable GenServers that could interfere with tests
4040
config :blockster_v2, :start_genservers, false
41+
42+
# Use mock Twilio client in tests
43+
config :blockster_v2, :twilio_client, TwilioClientMock

0 commit comments

Comments
 (0)