@@ -196,6 +196,27 @@ const MCP_TOOLS = [
196196 { tool : "query-docs" , server : "context7" } ,
197197] ;
198198
199+ const COMMANDS = [
200+ "generate" ,
201+ "edit" ,
202+ "explain" ,
203+ "refactor" ,
204+ "fix" ,
205+ "test" ,
206+ "review" ,
207+ "document" ,
208+ "optimize" ,
209+ "debug" ,
210+ ] ;
211+
212+ const EVENT_KINDS = [
213+ "Usage-based" ,
214+ "Included in Business" ,
215+ "Included in Business" ,
216+ "Included in Business" ,
217+ "Errored, Not Charged" ,
218+ ] ;
219+
199220const CLIENT_VERSIONS = [
200221 "2.2.36" ,
201222 "2.2.43" ,
@@ -461,15 +482,15 @@ function run() {
461482 metric : "spend" ,
462483 value : rand ( 5000 , 20000 ) ,
463484 threshold : rand ( 2000 , 5000 ) ,
464- msg : `${ user . name } : daily spend spiked to $${ rand ( 50 , 200 ) } (${ rand ( 3 , 6 ) } .${ rand ( 1 , 9 ) } x their 7-day avg) — model: ${ user . primaryModel } ` ,
485+ msg : `${ user . name } : daily spend spiked to $${ rand ( 50 , 200 ) } (${ rand ( 3 , 6 ) } .${ rand ( 1 , 9 ) } x their 7-day avg) - model: ${ user . primaryModel } ` ,
465486 } ,
466487 {
467- type : "trend " ,
468- severity : "warning " ,
469- metric : "spend " ,
470- value : rand ( 30000 , 100000 ) ,
471- threshold : rand ( 10000 , 30000 ) ,
472- msg : `${ user . name } : cycle spend $ ${ rand ( 300 , 1000 ) } is ${ rand ( 3 , 6 ) } . ${ rand ( 1 , 9 ) } x the team median — model: ${ user . primaryModel } ` ,
488+ type : "threshold " ,
489+ severity : "info " ,
490+ metric : "plan_exhausted " ,
491+ value : rand ( 50 , 500 ) ,
492+ threshold : 0 ,
493+ msg : `${ user . name } : exceeded included plan usage on day ${ rand ( 3 , 14 ) } of cycle. ${ rand ( 50 , 500 ) } extra requests billed since. ` ,
473494 } ,
474495 ] ;
475496 const anomaly = pick ( types ) ;
@@ -634,9 +655,150 @@ function run() {
634655 } ) ;
635656 cvTx ( ) ;
636657
658+ const eventStmt = db . prepare (
659+ `INSERT INTO usage_events (user_email, timestamp, model, kind, max_mode, requests_cost_cents,
660+ total_cents, total_tokens, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,
661+ is_chargeable, is_headless) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` ,
662+ ) ;
663+ const eventTx = db . transaction ( ( ) => {
664+ for ( let d = 0 ; d < DAYS ; d ++ ) {
665+ const date = dateStr ( DAYS - 1 - d ) ;
666+ for ( const user of userProfiles ) {
667+ const eventsPerDay =
668+ user . activityLevel === "high"
669+ ? rand ( 10 , 40 )
670+ : user . activityLevel === "medium"
671+ ? rand ( 3 , 15 )
672+ : rand ( 0 , 5 ) ;
673+ for ( let e = 0 ; e < eventsPerDay ; e ++ ) {
674+ const model =
675+ Math . random ( ) < 0.8 ? user . primaryModel : weightedPick ( MODELS , MODEL_WEIGHTS ) ;
676+ const kind = pick ( EVENT_KINDS ) ;
677+ const isMax = model . includes ( "-max" ) ? 1 : 0 ;
678+ const inputTokens = rand ( 500 , 50000 ) ;
679+ const outputTokens = rand ( 100 , 20000 ) ;
680+ const cacheRead = rand ( 0 , inputTokens ) ;
681+ const cacheWrite = rand ( 0 , Math . floor ( inputTokens * 0.3 ) ) ;
682+ const totalCents = + (
683+ ( ( inputTokens + outputTokens ) * 0.001 + ( isMax ? 2 : 0.3 ) ) *
684+ ( 0.5 + Math . random ( ) )
685+ ) . toFixed ( 2 ) ;
686+ const hour = rand ( 7 , 22 ) ;
687+ const minute = rand ( 0 , 59 ) ;
688+ const ts = String (
689+ new Date (
690+ `${ date } T${ String ( hour ) . padStart ( 2 , "0" ) } :${ String ( minute ) . padStart ( 2 , "0" ) } :${ String ( rand ( 0 , 59 ) ) . padStart ( 2 , "0" ) } Z` ,
691+ ) . getTime ( ) ,
692+ ) ;
693+ eventStmt . run (
694+ user . email ,
695+ ts ,
696+ model ,
697+ kind ,
698+ isMax ,
699+ totalCents ,
700+ totalCents ,
701+ inputTokens + outputTokens ,
702+ inputTokens ,
703+ outputTokens ,
704+ cacheRead ,
705+ cacheWrite ,
706+ 1 ,
707+ 0 ,
708+ ) ;
709+ }
710+ }
711+ }
712+ } ) ;
713+ eventTx ( ) ;
714+
715+ const cmdStmt = db . prepare (
716+ "INSERT INTO analytics_commands (date, command_name, usage) VALUES (?, ?, ?)" ,
717+ ) ;
718+ const cmdTx = db . transaction ( ( ) => {
719+ for ( let d = 0 ; d < DAYS ; d ++ ) {
720+ const date = dateStr ( DAYS - 1 - d ) ;
721+ for ( const cmd of COMMANDS ) {
722+ cmdStmt . run ( date , cmd , rand ( 5 , 150 ) ) ;
723+ }
724+ }
725+ } ) ;
726+ cmdTx ( ) ;
727+
728+ const planStmt = db . prepare ( "INSERT INTO analytics_plans (date, model, usage) VALUES (?, ?, ?)" ) ;
729+ const planTx = db . transaction ( ( ) => {
730+ for ( let d = 0 ; d < DAYS ; d ++ ) {
731+ const date = dateStr ( DAYS - 1 - d ) ;
732+ for ( let m = 0 ; m < Math . min ( 5 , MODELS . length ) ; m ++ ) {
733+ planStmt . run ( date , MODELS [ m ] , rand ( 1 , 30 ) ) ;
734+ }
735+ }
736+ } ) ;
737+ planTx ( ) ;
738+
637739 const metaStmt = db . prepare ( "INSERT INTO metadata (key, value, updated_at) VALUES (?, ?, ?)" ) ;
638740 metaStmt . run ( "cycle_start" , CYCLE_START , now ) ;
639741 metaStmt . run ( "cycle_end" , CYCLE_END , now ) ;
742+ metaStmt . run ( "limited_users_count" , "3" , now ) ;
743+ metaStmt . run ( "team_budget_threshold" , "15000" , now ) ;
744+
745+ const teamAnomalyDetected = `${ dateStr ( 1 ) } 09:00:00` ;
746+ const teamAnomalyAlerted = `${ dateStr ( 1 ) } 09:00:05` ;
747+ const teamResult = anomalyStmt . run (
748+ "team" ,
749+ "threshold" ,
750+ "warning" ,
751+ "users_limited" ,
752+ 3 ,
753+ 0 ,
754+ "3 team members are limited and unable to make requests. Review team spend limits on the Cursor dashboard." ,
755+ teamAnomalyDetected ,
756+ null ,
757+ teamAnomalyAlerted ,
758+ null ,
759+ null ,
760+ null ,
761+ ) ;
762+ incidentStmt . run (
763+ Number ( teamResult . lastInsertRowid ) ,
764+ "team" ,
765+ "open" ,
766+ teamAnomalyDetected ,
767+ teamAnomalyAlerted ,
768+ null ,
769+ null ,
770+ 2 ,
771+ null ,
772+ null ,
773+ ) ;
774+
775+ const budgetResult = anomalyStmt . run (
776+ "team" ,
777+ "threshold" ,
778+ "warning" ,
779+ "team_budget" ,
780+ 1310982 ,
781+ 1500000 ,
782+ "Team spend $13,110 has reached the $15,000 budget threshold (87%)." ,
783+ `${ dateStr ( 0 ) } 10:00:00` ,
784+ null ,
785+ `${ dateStr ( 0 ) } 10:00:05` ,
786+ null ,
787+ null ,
788+ null ,
789+ ) ;
790+ incidentStmt . run (
791+ Number ( budgetResult . lastInsertRowid ) ,
792+ "team" ,
793+ "open" ,
794+ `${ dateStr ( 0 ) } 10:00:00` ,
795+ `${ dateStr ( 0 ) } 10:00:05` ,
796+ null ,
797+ null ,
798+ 1 ,
799+ null ,
800+ null ,
801+ ) ;
640802
641803 db . close ( ) ;
642804 console . log ( `Mock database generated at ${ DB_PATH } ` ) ;
@@ -706,7 +868,7 @@ function createSchema(db: Database.Database) {
706868 CREATE TABLE IF NOT EXISTS daily_spend (
707869 date TEXT NOT NULL, email TEXT NOT NULL, spend_cents INTEGER NOT NULL DEFAULT 0,
708870 cycle_start TEXT NOT NULL, collected_at TEXT NOT NULL DEFAULT (datetime('now')),
709- PRIMARY KEY (date, email, cycle_start )
871+ PRIMARY KEY (date, email)
710872 );
711873 CREATE INDEX IF NOT EXISTS idx_daily_spend_email ON daily_spend(email);
712874 CREATE INDEX IF NOT EXISTS idx_daily_spend_date ON daily_spend(date);
@@ -756,6 +918,16 @@ function createSchema(db: Database.Database) {
756918 percentage REAL NOT NULL DEFAULT 0, collected_at TEXT NOT NULL DEFAULT (datetime('now')),
757919 PRIMARY KEY (date, version)
758920 );
921+ CREATE TABLE IF NOT EXISTS analytics_commands (
922+ date TEXT NOT NULL, command_name TEXT NOT NULL, usage INTEGER NOT NULL DEFAULT 0,
923+ collected_at TEXT NOT NULL DEFAULT (datetime('now')),
924+ PRIMARY KEY (date, command_name)
925+ );
926+ CREATE TABLE IF NOT EXISTS analytics_plans (
927+ date TEXT NOT NULL, model TEXT NOT NULL, usage INTEGER NOT NULL DEFAULT 0,
928+ collected_at TEXT NOT NULL DEFAULT (datetime('now')),
929+ PRIMARY KEY (date, model)
930+ );
759931 CREATE TABLE IF NOT EXISTS metadata (
760932 key TEXT PRIMARY KEY, value TEXT NOT NULL,
761933 updated_at TEXT NOT NULL DEFAULT (datetime('now'))
0 commit comments