╔═════════════════════════════════════════════════════════════════════╗
║ Red ───► Green ───►[TCR]───► Refactor ───►[TCR]───► Done ║
║ ║
║ [TCR] = test ──┬── pass ──► commit ──► continue ║
║ └── fail ──► REVERT ──► RETHINK ║
║ ║
| For generating stories and tasks from a video, use the following instructions: | |
| <INSTRUCTIONS> | |
| Act as a world-class technical product manager. Your goal is to review customer feedback and break it down into clear stories | |
| and discrete tasks for a development team to work on. Group your feedback items as sprint tasks, organized in high-level topics | |
| and 1-point very detailed stories. Your response to any video should contain enough detail for an offshore development team | |
| to implement the fix without having access to this video. Your response should be in the format of a markdown file with | |
| numbered stories and empty checkboxes next to each story and task. | |
| </INSTRUCTIONS> | |
| For refining the stories in the cursor-tasks file, use the following instructions: |
| // ==UserScript== | |
| // @name Add AlpineJs to Tailwind UI | |
| // @namespace http://tampermonkey.net/ | |
| // @version 3.0 | |
| // @description Add Alpine JS code to Tailwind Ui copy/paste | |
| // @author https://gist.github.com/KevinBatdorf/8bd5f808fff6a59e100dfa08a7431822 | |
| // @match https://tailwindui.com/components/* | |
| // @grant none | |
| // ==/UserScript== |
First of all, please note that token expiration and revoking are two different things.
- Expiration only happens for web apps, not for native mobile apps, because native apps never expire.
- Revoking only happens when (1) uses click the logout button on the website or native Apps;(2) users reset their passwords; (3) users revoke their tokens explicitly in the administration panel.
A JWT token that never expires is dangerous if the token is stolen then someone can always access the user's data.
Quoted from JWT RFC:
Vue.js is an amazing framework, which can be as powerful as Angular or React, the two big heavy hitters in the world of front-end frameworks.
However, most of Vue's ease-of-use is due to the use of Observables - a pattern that triggers re-renders and other function calls with the reassignment of a variable.
| const functions = require('firebase-functions'); // To stub config() | |
| const admin = require('firebase-admin'); // To get credential cert for initializeApp | |
| const firebase = require('firebase'); // To sign in test user and test database writes | |
| const assert = require('chai').assert; | |
| const sinon = require('sinon'); | |
| // https://firebase.google.com/docs/functions/unit-testing | |
| // The functions make use of 'firebase-admin', whereas client-side code uses 'firebase'. | |
| // We initialze 'firebase' here to mock client-side code. |
| var camelCase = require('lodash.camelcase'); | |
| const {Map, Record, List} = require('immutable'); | |
| class Todo extends Record({ description: null, completed: false }) { | |
| toggle() { | |
| return this.set('completed', !this.completed); | |
| } | |
| } | |
| const InitialTodoApp = Record({ |
| # Credit Brandon Weiss of http://anti-pattern.com/dirty-associations-with-activerecord | |
| # app/models/dirty_associations.rb | |
| module DirtyAssociations | |
| attr_accessor :dirty | |
| attr_accessor :_record_changes | |
| def make_dirty(record) | |
| self.dirty = true | |
| self._record_changes = record |
#Heroku, Ruby on Rails and PhantomJS
In this post, I’m going to show you how to modify an existing Ruby on Rails app running on Heroku’s Cedar stack to use PhantomJS for screen scraping. If you’ve never heard of PhantomJS, it’s a command-line WebKit-based browser (that supports JavaScript, cookies, etc.).
Let’s get started. This is a high-level overview of the required steps:
- Modify your app to use multiple Heroku buildpacks.
- Extend your app to use both the Ruby as well as the PhantomJS buildpacks.
- Confirm that everything worked.
| @PageSpinner = | |
| spin: (ms=500)-> | |
| @spinner = setTimeout( (=> @add_spinner()), ms) | |
| $(document).on 'page:change', => | |
| @remove_spinner() | |
| spinner_html: ' | |
| <div class="modal hide fade" id="page-spinner"> | |
| <div class="modal-head card-title">Please Wait...</div> | |
| <div class="modal-body card-body"> | |
| <i class="icon-spinner icon-spin icon-2x"></i> |