Schedule posts to Bluesky with Cloudflare workers. skyscheduler.work
cf tool bsky-tool cloudflare bluesky schedule bsky service social-media cloudflare-workers

attempt to improve d1 lookups

remove primary key on violations, replace with shitty other key

+739 -1
+18
migrations/0010_smiling_namorita.sql
··· 1 + PRAGMA foreign_keys=OFF;--> statement-breakpoint 2 + CREATE TABLE `__new_violations` ( 3 + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, 4 + `user` text NOT NULL, 5 + `tosViolation` integer DEFAULT false, 6 + `userPassInvalid` integer DEFAULT false, 7 + `accountSuspended` integer DEFAULT false, 8 + `accountGone` integer DEFAULT false, 9 + `mediaTooBig` integer DEFAULT false, 10 + `created_at` integer DEFAULT CURRENT_TIMESTAMP NOT NULL, 11 + FOREIGN KEY (`user`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade 12 + ); 13 + --> statement-breakpoint 14 + INSERT INTO `__new_violations`("id", "user", "tosViolation", "userPassInvalid", "accountSuspended", "accountGone", "mediaTooBig", "created_at") SELECT "id", "user", "tosViolation", "userPassInvalid", "accountSuspended", "accountGone", "mediaTooBig", "created_at" FROM `violations`;--> statement-breakpoint 15 + DROP TABLE `violations`;--> statement-breakpoint 16 + ALTER TABLE `__new_violations` RENAME TO `violations`;--> statement-breakpoint 17 + PRAGMA foreign_keys=ON;--> statement-breakpoint 18 + CREATE INDEX `violations_user_idx` ON `violations` (`user`);
+712
migrations/meta/0010_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "cd9e512b-7b3b-4ef3-91b6-3b14ddfa11b2", 5 + "prevId": "8a24986d-66d1-42a0-89ed-67480e69e780", 6 + "tables": { 7 + "accounts": { 8 + "name": "accounts", 9 + "columns": { 10 + "id": { 11 + "name": "id", 12 + "type": "text", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "account_id": { 18 + "name": "account_id", 19 + "type": "text", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "provider_id": { 25 + "name": "provider_id", 26 + "type": "text", 27 + "primaryKey": false, 28 + "notNull": true, 29 + "autoincrement": false 30 + }, 31 + "user_id": { 32 + "name": "user_id", 33 + "type": "text", 34 + "primaryKey": false, 35 + "notNull": true, 36 + "autoincrement": false 37 + }, 38 + "access_token": { 39 + "name": "access_token", 40 + "type": "text", 41 + "primaryKey": false, 42 + "notNull": false, 43 + "autoincrement": false 44 + }, 45 + "refresh_token": { 46 + "name": "refresh_token", 47 + "type": "text", 48 + "primaryKey": false, 49 + "notNull": false, 50 + "autoincrement": false 51 + }, 52 + "id_token": { 53 + "name": "id_token", 54 + "type": "text", 55 + "primaryKey": false, 56 + "notNull": false, 57 + "autoincrement": false 58 + }, 59 + "access_token_expires_at": { 60 + "name": "access_token_expires_at", 61 + "type": "integer", 62 + "primaryKey": false, 63 + "notNull": false, 64 + "autoincrement": false 65 + }, 66 + "refresh_token_expires_at": { 67 + "name": "refresh_token_expires_at", 68 + "type": "integer", 69 + "primaryKey": false, 70 + "notNull": false, 71 + "autoincrement": false 72 + }, 73 + "scope": { 74 + "name": "scope", 75 + "type": "text", 76 + "primaryKey": false, 77 + "notNull": false, 78 + "autoincrement": false 79 + }, 80 + "password": { 81 + "name": "password", 82 + "type": "text", 83 + "primaryKey": false, 84 + "notNull": false, 85 + "autoincrement": false 86 + }, 87 + "created_at": { 88 + "name": "created_at", 89 + "type": "integer", 90 + "primaryKey": false, 91 + "notNull": true, 92 + "autoincrement": false, 93 + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" 94 + }, 95 + "updated_at": { 96 + "name": "updated_at", 97 + "type": "integer", 98 + "primaryKey": false, 99 + "notNull": true, 100 + "autoincrement": false 101 + } 102 + }, 103 + "indexes": { 104 + "accounts_userId_idx": { 105 + "name": "accounts_userId_idx", 106 + "columns": [ 107 + "user_id" 108 + ], 109 + "isUnique": false 110 + } 111 + }, 112 + "foreignKeys": { 113 + "accounts_user_id_users_id_fk": { 114 + "name": "accounts_user_id_users_id_fk", 115 + "tableFrom": "accounts", 116 + "tableTo": "users", 117 + "columnsFrom": [ 118 + "user_id" 119 + ], 120 + "columnsTo": [ 121 + "id" 122 + ], 123 + "onDelete": "cascade", 124 + "onUpdate": "no action" 125 + } 126 + }, 127 + "compositePrimaryKeys": {}, 128 + "uniqueConstraints": {}, 129 + "checkConstraints": {} 130 + }, 131 + "sessions": { 132 + "name": "sessions", 133 + "columns": { 134 + "id": { 135 + "name": "id", 136 + "type": "text", 137 + "primaryKey": true, 138 + "notNull": true, 139 + "autoincrement": false 140 + }, 141 + "expires_at": { 142 + "name": "expires_at", 143 + "type": "integer", 144 + "primaryKey": false, 145 + "notNull": true, 146 + "autoincrement": false 147 + }, 148 + "token": { 149 + "name": "token", 150 + "type": "text", 151 + "primaryKey": false, 152 + "notNull": true, 153 + "autoincrement": false 154 + }, 155 + "created_at": { 156 + "name": "created_at", 157 + "type": "integer", 158 + "primaryKey": false, 159 + "notNull": true, 160 + "autoincrement": false, 161 + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" 162 + }, 163 + "updated_at": { 164 + "name": "updated_at", 165 + "type": "integer", 166 + "primaryKey": false, 167 + "notNull": true, 168 + "autoincrement": false 169 + }, 170 + "ip_address": { 171 + "name": "ip_address", 172 + "type": "text", 173 + "primaryKey": false, 174 + "notNull": false, 175 + "autoincrement": false 176 + }, 177 + "user_agent": { 178 + "name": "user_agent", 179 + "type": "text", 180 + "primaryKey": false, 181 + "notNull": false, 182 + "autoincrement": false 183 + }, 184 + "user_id": { 185 + "name": "user_id", 186 + "type": "text", 187 + "primaryKey": false, 188 + "notNull": true, 189 + "autoincrement": false 190 + } 191 + }, 192 + "indexes": { 193 + "sessions_token_unique": { 194 + "name": "sessions_token_unique", 195 + "columns": [ 196 + "token" 197 + ], 198 + "isUnique": true 199 + }, 200 + "sessions_userId_idx": { 201 + "name": "sessions_userId_idx", 202 + "columns": [ 203 + "user_id" 204 + ], 205 + "isUnique": false 206 + } 207 + }, 208 + "foreignKeys": { 209 + "sessions_user_id_users_id_fk": { 210 + "name": "sessions_user_id_users_id_fk", 211 + "tableFrom": "sessions", 212 + "tableTo": "users", 213 + "columnsFrom": [ 214 + "user_id" 215 + ], 216 + "columnsTo": [ 217 + "id" 218 + ], 219 + "onDelete": "cascade", 220 + "onUpdate": "no action" 221 + } 222 + }, 223 + "compositePrimaryKeys": {}, 224 + "uniqueConstraints": {}, 225 + "checkConstraints": {} 226 + }, 227 + "users": { 228 + "name": "users", 229 + "columns": { 230 + "id": { 231 + "name": "id", 232 + "type": "text", 233 + "primaryKey": true, 234 + "notNull": true, 235 + "autoincrement": false 236 + }, 237 + "name": { 238 + "name": "name", 239 + "type": "text", 240 + "primaryKey": false, 241 + "notNull": true, 242 + "autoincrement": false 243 + }, 244 + "email": { 245 + "name": "email", 246 + "type": "text", 247 + "primaryKey": false, 248 + "notNull": true, 249 + "autoincrement": false 250 + }, 251 + "email_verified": { 252 + "name": "email_verified", 253 + "type": "integer", 254 + "primaryKey": false, 255 + "notNull": true, 256 + "autoincrement": false 257 + }, 258 + "image": { 259 + "name": "image", 260 + "type": "text", 261 + "primaryKey": false, 262 + "notNull": false, 263 + "autoincrement": false 264 + }, 265 + "created_at": { 266 + "name": "created_at", 267 + "type": "integer", 268 + "primaryKey": false, 269 + "notNull": true, 270 + "autoincrement": false 271 + }, 272 + "updated_at": { 273 + "name": "updated_at", 274 + "type": "integer", 275 + "primaryKey": false, 276 + "notNull": true, 277 + "autoincrement": false 278 + }, 279 + "username": { 280 + "name": "username", 281 + "type": "text", 282 + "primaryKey": false, 283 + "notNull": false, 284 + "autoincrement": false 285 + }, 286 + "display_username": { 287 + "name": "display_username", 288 + "type": "text", 289 + "primaryKey": false, 290 + "notNull": false, 291 + "autoincrement": false 292 + }, 293 + "bsky_app_pass": { 294 + "name": "bsky_app_pass", 295 + "type": "text", 296 + "primaryKey": false, 297 + "notNull": true, 298 + "autoincrement": false 299 + }, 300 + "pds": { 301 + "name": "pds", 302 + "type": "text", 303 + "primaryKey": false, 304 + "notNull": true, 305 + "autoincrement": false, 306 + "default": "'https://bsky.social'" 307 + } 308 + }, 309 + "indexes": { 310 + "users_email_unique": { 311 + "name": "users_email_unique", 312 + "columns": [ 313 + "email" 314 + ], 315 + "isUnique": true 316 + }, 317 + "users_username_unique": { 318 + "name": "users_username_unique", 319 + "columns": [ 320 + "username" 321 + ], 322 + "isUnique": true 323 + } 324 + }, 325 + "foreignKeys": {}, 326 + "compositePrimaryKeys": {}, 327 + "uniqueConstraints": {}, 328 + "checkConstraints": {} 329 + }, 330 + "verifications": { 331 + "name": "verifications", 332 + "columns": { 333 + "id": { 334 + "name": "id", 335 + "type": "text", 336 + "primaryKey": true, 337 + "notNull": true, 338 + "autoincrement": false 339 + }, 340 + "identifier": { 341 + "name": "identifier", 342 + "type": "text", 343 + "primaryKey": false, 344 + "notNull": true, 345 + "autoincrement": false 346 + }, 347 + "value": { 348 + "name": "value", 349 + "type": "text", 350 + "primaryKey": false, 351 + "notNull": true, 352 + "autoincrement": false 353 + }, 354 + "expires_at": { 355 + "name": "expires_at", 356 + "type": "integer", 357 + "primaryKey": false, 358 + "notNull": true, 359 + "autoincrement": false 360 + }, 361 + "created_at": { 362 + "name": "created_at", 363 + "type": "integer", 364 + "primaryKey": false, 365 + "notNull": true, 366 + "autoincrement": false, 367 + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" 368 + }, 369 + "updated_at": { 370 + "name": "updated_at", 371 + "type": "integer", 372 + "primaryKey": false, 373 + "notNull": true, 374 + "autoincrement": false, 375 + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" 376 + } 377 + }, 378 + "indexes": { 379 + "verifications_identifier_idx": { 380 + "name": "verifications_identifier_idx", 381 + "columns": [ 382 + "identifier" 383 + ], 384 + "isUnique": false 385 + } 386 + }, 387 + "foreignKeys": {}, 388 + "compositePrimaryKeys": {}, 389 + "uniqueConstraints": {}, 390 + "checkConstraints": {} 391 + }, 392 + "posts": { 393 + "name": "posts", 394 + "columns": { 395 + "uuid": { 396 + "name": "uuid", 397 + "type": "text", 398 + "primaryKey": true, 399 + "notNull": true, 400 + "autoincrement": false 401 + }, 402 + "content": { 403 + "name": "content", 404 + "type": "text", 405 + "primaryKey": false, 406 + "notNull": true, 407 + "autoincrement": false 408 + }, 409 + "scheduled_date": { 410 + "name": "scheduled_date", 411 + "type": "integer", 412 + "primaryKey": false, 413 + "notNull": true, 414 + "autoincrement": false 415 + }, 416 + "posted": { 417 + "name": "posted", 418 + "type": "integer", 419 + "primaryKey": false, 420 + "notNull": false, 421 + "autoincrement": false, 422 + "default": false 423 + }, 424 + "postNow": { 425 + "name": "postNow", 426 + "type": "integer", 427 + "primaryKey": false, 428 + "notNull": false, 429 + "autoincrement": false, 430 + "default": false 431 + }, 432 + "embedContent": { 433 + "name": "embedContent", 434 + "type": "text", 435 + "primaryKey": false, 436 + "notNull": true, 437 + "autoincrement": false, 438 + "default": "(json_array())" 439 + }, 440 + "uri": { 441 + "name": "uri", 442 + "type": "text", 443 + "primaryKey": false, 444 + "notNull": false, 445 + "autoincrement": false 446 + }, 447 + "cid": { 448 + "name": "cid", 449 + "type": "text", 450 + "primaryKey": false, 451 + "notNull": false, 452 + "autoincrement": false 453 + }, 454 + "contentLabel": { 455 + "name": "contentLabel", 456 + "type": "text", 457 + "primaryKey": false, 458 + "notNull": true, 459 + "autoincrement": false, 460 + "default": "'None'" 461 + }, 462 + "created_at": { 463 + "name": "created_at", 464 + "type": "integer", 465 + "primaryKey": false, 466 + "notNull": true, 467 + "autoincrement": false, 468 + "default": "CURRENT_TIMESTAMP" 469 + }, 470 + "updated_at": { 471 + "name": "updated_at", 472 + "type": "integer", 473 + "primaryKey": false, 474 + "notNull": false, 475 + "autoincrement": false 476 + }, 477 + "user": { 478 + "name": "user", 479 + "type": "text", 480 + "primaryKey": false, 481 + "notNull": true, 482 + "autoincrement": false 483 + } 484 + }, 485 + "indexes": { 486 + "scheduledDate_idx": { 487 + "name": "scheduledDate_idx", 488 + "columns": [ 489 + "scheduled_date" 490 + ], 491 + "isUnique": false 492 + }, 493 + "user_idx": { 494 + "name": "user_idx", 495 + "columns": [ 496 + "user" 497 + ], 498 + "isUnique": false 499 + }, 500 + "postedUpdate_idx": { 501 + "name": "postedUpdate_idx", 502 + "columns": [ 503 + "updated_at", 504 + "posted" 505 + ], 506 + "isUnique": false, 507 + "where": "posted = 1" 508 + }, 509 + "postedUUID_idx": { 510 + "name": "postedUUID_idx", 511 + "columns": [ 512 + "uuid", 513 + "posted" 514 + ], 515 + "isUnique": false 516 + }, 517 + "postNowScheduledDatePosted_idx": { 518 + "name": "postNowScheduledDatePosted_idx", 519 + "columns": [ 520 + "posted", 521 + "scheduled_date", 522 + "postNow" 523 + ], 524 + "isUnique": false, 525 + "where": "posted = 0 and postNow <> 0" 526 + } 527 + }, 528 + "foreignKeys": { 529 + "posts_user_users_id_fk": { 530 + "name": "posts_user_users_id_fk", 531 + "tableFrom": "posts", 532 + "tableTo": "users", 533 + "columnsFrom": [ 534 + "user" 535 + ], 536 + "columnsTo": [ 537 + "id" 538 + ], 539 + "onDelete": "cascade", 540 + "onUpdate": "no action" 541 + } 542 + }, 543 + "compositePrimaryKeys": {}, 544 + "uniqueConstraints": {}, 545 + "checkConstraints": {} 546 + }, 547 + "reposts": { 548 + "name": "reposts", 549 + "columns": { 550 + "id": { 551 + "name": "id", 552 + "type": "integer", 553 + "primaryKey": true, 554 + "notNull": true, 555 + "autoincrement": true 556 + }, 557 + "post_uuid": { 558 + "name": "post_uuid", 559 + "type": "text", 560 + "primaryKey": false, 561 + "notNull": true, 562 + "autoincrement": false 563 + }, 564 + "scheduled_date": { 565 + "name": "scheduled_date", 566 + "type": "integer", 567 + "primaryKey": false, 568 + "notNull": true, 569 + "autoincrement": false 570 + } 571 + }, 572 + "indexes": { 573 + "repost_scheduledDate_idx": { 574 + "name": "repost_scheduledDate_idx", 575 + "columns": [ 576 + "scheduled_date" 577 + ], 578 + "isUnique": false 579 + }, 580 + "repost_postid_idx": { 581 + "name": "repost_postid_idx", 582 + "columns": [ 583 + "post_uuid" 584 + ], 585 + "isUnique": false 586 + } 587 + }, 588 + "foreignKeys": { 589 + "reposts_post_uuid_posts_uuid_fk": { 590 + "name": "reposts_post_uuid_posts_uuid_fk", 591 + "tableFrom": "reposts", 592 + "tableTo": "posts", 593 + "columnsFrom": [ 594 + "post_uuid" 595 + ], 596 + "columnsTo": [ 597 + "uuid" 598 + ], 599 + "onDelete": "cascade", 600 + "onUpdate": "no action" 601 + } 602 + }, 603 + "compositePrimaryKeys": {}, 604 + "uniqueConstraints": {}, 605 + "checkConstraints": {} 606 + }, 607 + "violations": { 608 + "name": "violations", 609 + "columns": { 610 + "id": { 611 + "name": "id", 612 + "type": "integer", 613 + "primaryKey": true, 614 + "notNull": true, 615 + "autoincrement": true 616 + }, 617 + "user": { 618 + "name": "user", 619 + "type": "text", 620 + "primaryKey": false, 621 + "notNull": true, 622 + "autoincrement": false 623 + }, 624 + "tosViolation": { 625 + "name": "tosViolation", 626 + "type": "integer", 627 + "primaryKey": false, 628 + "notNull": false, 629 + "autoincrement": false, 630 + "default": false 631 + }, 632 + "userPassInvalid": { 633 + "name": "userPassInvalid", 634 + "type": "integer", 635 + "primaryKey": false, 636 + "notNull": false, 637 + "autoincrement": false, 638 + "default": false 639 + }, 640 + "accountSuspended": { 641 + "name": "accountSuspended", 642 + "type": "integer", 643 + "primaryKey": false, 644 + "notNull": false, 645 + "autoincrement": false, 646 + "default": false 647 + }, 648 + "accountGone": { 649 + "name": "accountGone", 650 + "type": "integer", 651 + "primaryKey": false, 652 + "notNull": false, 653 + "autoincrement": false, 654 + "default": false 655 + }, 656 + "mediaTooBig": { 657 + "name": "mediaTooBig", 658 + "type": "integer", 659 + "primaryKey": false, 660 + "notNull": false, 661 + "autoincrement": false, 662 + "default": false 663 + }, 664 + "created_at": { 665 + "name": "created_at", 666 + "type": "integer", 667 + "primaryKey": false, 668 + "notNull": true, 669 + "autoincrement": false, 670 + "default": "CURRENT_TIMESTAMP" 671 + } 672 + }, 673 + "indexes": { 674 + "violations_user_idx": { 675 + "name": "violations_user_idx", 676 + "columns": [ 677 + "user" 678 + ], 679 + "isUnique": false 680 + } 681 + }, 682 + "foreignKeys": { 683 + "violations_user_users_id_fk": { 684 + "name": "violations_user_users_id_fk", 685 + "tableFrom": "violations", 686 + "tableTo": "users", 687 + "columnsFrom": [ 688 + "user" 689 + ], 690 + "columnsTo": [ 691 + "id" 692 + ], 693 + "onDelete": "cascade", 694 + "onUpdate": "no action" 695 + } 696 + }, 697 + "compositePrimaryKeys": {}, 698 + "uniqueConstraints": {}, 699 + "checkConstraints": {} 700 + } 701 + }, 702 + "views": {}, 703 + "enums": {}, 704 + "_meta": { 705 + "schemas": {}, 706 + "tables": {}, 707 + "columns": {} 708 + }, 709 + "internal": { 710 + "indexes": {} 711 + } 712 + }
+7
migrations/meta/_journal.json
··· 71 71 "when": 1767672841247, 72 72 "tag": "0009_first_black_cat", 73 73 "breakpoints": true 74 + }, 75 + { 76 + "idx": 10, 77 + "version": "6", 78 + "when": 1767758958868, 79 + "tag": "0010_smiling_namorita", 80 + "breakpoints": true 74 81 } 75 82 ] 76 83 }
+2 -1
src/db/app.schema.ts
··· 46 46 ]); 47 47 48 48 export const violations = sqliteTable('violations', { 49 + id: integer('id', { mode: 'number' }).primaryKey({ autoIncrement: true }), 49 50 userId: text("user") 50 51 .notNull() 51 - .references(() => users.id, { onDelete: "cascade" }).primaryKey(), 52 + .references(() => users.id, { onDelete: "cascade" }), 52 53 tosViolation: integer('tosViolation', { mode: 'boolean' }).default(false), 53 54 userPassInvalid: integer('userPassInvalid', { mode: 'boolean' }).default(false), 54 55 accountSuspended: integer('accountSuspended', { mode: 'boolean' }).default(false),