{"action":"created","comment":{"url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/comments/58042376","id":58042376,"diff_hunk":"@@ -0,0 +1,130 @@\n+/* This Source Code Form is subject to the terms of the Mozilla Public\n+ * License, v. 2.0. If a copy of the MPL was not distributed with this\n+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n+\n+/**\n+ * A model to represent the somewhat nebulous concept of an\n+ * \"event flow\". A single flow could be a user connecting a\n+ * new device to their Sync account, for instance.\n+ *\n+ * Each flow has two properties.\n+ *\n+ *   * flowId: 32-byte identifier hex-encoded as a string.\n+ *   * flowBeginTime: server-generated timestamp.\n+ *\n+ * When a new flow is begun, it should result in an activity\n+ * event being logged by the server. To that end, we push a\n+ * a `flow.begin` onto the metrics event array.\n+ *\n+ * There is some mess surrounding when to begin a new flow,\n+ * which necessitates equivalent mess in this model. It runs\n+ * something like this:\n+ *\n+ *   1. A user arriving at /signin or /signup constitutes the\n+ *      beginning of a flow, so a corresponding `flow.begin`\n+ *      event must be logged.\n+ *\n+ *   2. A user refreshing the page on /signin or /signup does\n+ *      not constitute a new flow, so events must not be logged\n+ *      in those cases. This is achieved by saving the flowId\n+ *      in local storage.\n+ *\n+ *   3. If a user signs in, then signs out, then signs in again,\n+ *      the second sign-in does count as a new flow, so a second\n+ *      `flow.begin` event must be logged. This is achieved by\n+ *      clearing the model and local storage when a user is signed\n+ *      out. Also note that in this case, since the navigation may\n+ *      have occurred entirely on the client, we might not have a\n+ *      server-generated flowBeginTime and must estimate the time\n+ *      instead.\n+ *\n+ *   4. If a user signs up on device A then confirms their email\n+ *      address on device B, the flow id must follow them onto\n+ *      the new device so that it can be propagated in requests\n+ *      to the auth server. This is achieved by also setting flowId\n+ *      as a property of the user model, which is serialised into\n+ *      the resume token.","path":"app/scripts/models/flow.js","position":46,"original_position":46,"commit_id":"8e499e41c3c5439ece942f24b67742e04a6e8018","original_commit_id":"8e499e41c3c5439ece942f24b67742e04a6e8018","user":{"login":"shane-tomlinson","id":848085,"avatar_url":"https://avatars.githubusercontent.com/u/848085?v=3","gravatar_id":"","url":"https://api.github.com/users/shane-tomlinson","html_url":"https://github.com/shane-tomlinson","followers_url":"https://api.github.com/users/shane-tomlinson/followers","following_url":"https://api.github.com/users/shane-tomlinson/following{/other_user}","gists_url":"https://api.github.com/users/shane-tomlinson/gists{/gist_id}","starred_url":"https://api.github.com/users/shane-tomlinson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shane-tomlinson/subscriptions","organizations_url":"https://api.github.com/users/shane-tomlinson/orgs","repos_url":"https://api.github.com/users/shane-tomlinson/repos","events_url":"https://api.github.com/users/shane-tomlinson/events{/privacy}","received_events_url":"https://api.github.com/users/shane-tomlinson/received_events","type":"User","site_admin":false},"body":"This is an excellent explanation. Thanks for the context. Full of answers to \"WHY?????\"","created_at":"2016-03-31T12:08:35Z","updated_at":"2016-03-31T12:08:35Z","html_url":"https://github.com/mozilla/fxa-content-server/pull/3619#discussion_r58042376","pull_request_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619","_links":{"self":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/comments/58042376"},"html":{"href":"https://github.com/mozilla/fxa-content-server/pull/3619#discussion_r58042376"},"pull_request":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619"}}},"pull_request":{"url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619","id":63930153,"html_url":"https://github.com/mozilla/fxa-content-server/pull/3619","diff_url":"https://github.com/mozilla/fxa-content-server/pull/3619.diff","patch_url":"https://github.com/mozilla/fxa-content-server/pull/3619.patch","issue_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/3619","number":3619,"state":"open","locked":false,"title":"feat(metrics): emit flow.begin activity event from metrics endpoint","user":{"login":"philbooth","id":64367,"avatar_url":"https://avatars.githubusercontent.com/u/64367?v=3","gravatar_id":"","url":"https://api.github.com/users/philbooth","html_url":"https://github.com/philbooth","followers_url":"https://api.github.com/users/philbooth/followers","following_url":"https://api.github.com/users/philbooth/following{/other_user}","gists_url":"https://api.github.com/users/philbooth/gists{/gist_id}","starred_url":"https://api.github.com/users/philbooth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/philbooth/subscriptions","organizations_url":"https://api.github.com/users/philbooth/orgs","repos_url":"https://api.github.com/users/philbooth/repos","events_url":"https://api.github.com/users/philbooth/events{/privacy}","received_events_url":"https://api.github.com/users/philbooth/received_events","type":"User","site_admin":false},"body":"Fixes #3608.\r\n\r\nLogic for emitting the event is:\r\n\r\n1. Server records the request time in the `GET /` handler and passes it to the client in the `data-flow-begin` attribute.\r\n2. In the client, the user model sets its own `flowId`. If there's one in the resume token, it uses that, otherwise it creates a new one.\r\n3. During `afterRender` for the `signUp` and `signIn` views, if that `flowId` is not already set on the metrics object, it and `flowBeginTime` are set and `flow.begin` is added to the array of metrics events. The conditional aspect of this is to prevent multiple events being emitted when a user switches between views.\r\n4. Back on the server, the handler for `POST /metrics` emits `flow.begin` activity events as indicated.\r\n\r\nThere is one thing I was particularly unsure about and would like to hear opinions about: **Should the user model unset its `flowId` in `signOutAccount`?**\r\n\r\nI'm not doing that at the moment but I can see the case for doing so; it would mean that extra `flow.begin` events are emitted for users that sign in, then sign out, then sign in again. Is that something we should handle?\r\n\r\nThe reason I wasn't sure is because it gets more complicated when resume tokens are involved. We'd need a way to signal that the resume token should be ignored when the user sets `flowId`, otherwise we'll end up with duplicate `flow.begin` events in the data. That seems like a can of worms, especially as I'm supposed to have all this finished by the end of the quarter. So maybe we could leave this bit for a follow-up? :grin:\r\n\r\n@shane-tomlinson, r?\r\n","created_at":"2016-03-23T18:25:39Z","updated_at":"2016-03-31T12:08:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b92490063c8077fd5f086869797814b0baa507dd","assignee":{"login":"philbooth","id":64367,"avatar_url":"https://avatars.githubusercontent.com/u/64367?v=3","gravatar_id":"","url":"https://api.github.com/users/philbooth","html_url":"https://github.com/philbooth","followers_url":"https://api.github.com/users/philbooth/followers","following_url":"https://api.github.com/users/philbooth/following{/other_user}","gists_url":"https://api.github.com/users/philbooth/gists{/gist_id}","starred_url":"https://api.github.com/users/philbooth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/philbooth/subscriptions","organizations_url":"https://api.github.com/users/philbooth/orgs","repos_url":"https://api.github.com/users/philbooth/repos","events_url":"https://api.github.com/users/philbooth/events{/privacy}","received_events_url":"https://api.github.com/users/philbooth/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619/commits","review_comments_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619/comments","review_comment_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/3619/comments","statuses_url":"https://api.github.com/repos/mozilla/fxa-content-server/statuses/8e499e41c3c5439ece942f24b67742e04a6e8018","head":{"label":"mozilla:phil/issue-3608","ref":"phil/issue-3608","sha":"8e499e41c3c5439ece942f24b67742e04a6e8018","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":11778024,"name":"fxa-content-server","full_name":"mozilla/fxa-content-server","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/fxa-content-server","description":"Firefox Accounts Content Server","fork":false,"url":"https://api.github.com/repos/mozilla/fxa-content-server","forks_url":"https://api.github.com/repos/mozilla/fxa-content-server/forks","keys_url":"https://api.github.com/repos/mozilla/fxa-content-server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/fxa-content-server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/fxa-content-server/teams","hooks_url":"https://api.github.com/repos/mozilla/fxa-content-server/hooks","issue_events_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/fxa-content-server/events","assignees_url":"https://api.github.com/repos/mozilla/fxa-content-server/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/fxa-content-server/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/fxa-content-server/tags","blobs_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/fxa-content-server/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/fxa-content-server/languages","stargazers_url":"https://api.github.com/repos/mozilla/fxa-content-server/stargazers","contributors_url":"https://api.github.com/repos/mozilla/fxa-content-server/contributors","subscribers_url":"https://api.github.com/repos/mozilla/fxa-content-server/subscribers","subscription_url":"https://api.github.com/repos/mozilla/fxa-content-server/subscription","commits_url":"https://api.github.com/repos/mozilla/fxa-content-server/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/fxa-content-server/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/fxa-content-server/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/fxa-content-server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/fxa-content-server/merges","archive_url":"https://api.github.com/repos/mozilla/fxa-content-server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/fxa-content-server/downloads","issues_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/fxa-content-server/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/fxa-content-server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/fxa-content-server/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/fxa-content-server/releases{/id}","deployments_url":"https://api.github.com/repos/mozilla/fxa-content-server/deployments","created_at":"2013-07-30T23:35:35Z","updated_at":"2016-03-27T04:11:12Z","pushed_at":"2016-03-31T10:59:07Z","git_url":"git://github.com/mozilla/fxa-content-server.git","ssh_url":"git@github.com:mozilla/fxa-content-server.git","clone_url":"https://github.com/mozilla/fxa-content-server.git","svn_url":"https://github.com/mozilla/fxa-content-server","homepage":"","size":15042,"stargazers_count":90,"watchers_count":90,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":56,"mirror_url":null,"open_issues_count":129,"forks":56,"open_issues":129,"watchers":90,"default_branch":"master"}},"base":{"label":"mozilla:master","ref":"master","sha":"31d42fab48f8a8e725dfa3f2b681912eafa8cf7c","user":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"repo":{"id":11778024,"name":"fxa-content-server","full_name":"mozilla/fxa-content-server","owner":{"login":"mozilla","id":131524,"avatar_url":"https://avatars.githubusercontent.com/u/131524?v=3","gravatar_id":"","url":"https://api.github.com/users/mozilla","html_url":"https://github.com/mozilla","followers_url":"https://api.github.com/users/mozilla/followers","following_url":"https://api.github.com/users/mozilla/following{/other_user}","gists_url":"https://api.github.com/users/mozilla/gists{/gist_id}","starred_url":"https://api.github.com/users/mozilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mozilla/subscriptions","organizations_url":"https://api.github.com/users/mozilla/orgs","repos_url":"https://api.github.com/users/mozilla/repos","events_url":"https://api.github.com/users/mozilla/events{/privacy}","received_events_url":"https://api.github.com/users/mozilla/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mozilla/fxa-content-server","description":"Firefox Accounts Content Server","fork":false,"url":"https://api.github.com/repos/mozilla/fxa-content-server","forks_url":"https://api.github.com/repos/mozilla/fxa-content-server/forks","keys_url":"https://api.github.com/repos/mozilla/fxa-content-server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mozilla/fxa-content-server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mozilla/fxa-content-server/teams","hooks_url":"https://api.github.com/repos/mozilla/fxa-content-server/hooks","issue_events_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/events{/number}","events_url":"https://api.github.com/repos/mozilla/fxa-content-server/events","assignees_url":"https://api.github.com/repos/mozilla/fxa-content-server/assignees{/user}","branches_url":"https://api.github.com/repos/mozilla/fxa-content-server/branches{/branch}","tags_url":"https://api.github.com/repos/mozilla/fxa-content-server/tags","blobs_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/refs{/sha}","trees_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mozilla/fxa-content-server/statuses/{sha}","languages_url":"https://api.github.com/repos/mozilla/fxa-content-server/languages","stargazers_url":"https://api.github.com/repos/mozilla/fxa-content-server/stargazers","contributors_url":"https://api.github.com/repos/mozilla/fxa-content-server/contributors","subscribers_url":"https://api.github.com/repos/mozilla/fxa-content-server/subscribers","subscription_url":"https://api.github.com/repos/mozilla/fxa-content-server/subscription","commits_url":"https://api.github.com/repos/mozilla/fxa-content-server/commits{/sha}","git_commits_url":"https://api.github.com/repos/mozilla/fxa-content-server/git/commits{/sha}","comments_url":"https://api.github.com/repos/mozilla/fxa-content-server/comments{/number}","issue_comment_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/comments{/number}","contents_url":"https://api.github.com/repos/mozilla/fxa-content-server/contents/{+path}","compare_url":"https://api.github.com/repos/mozilla/fxa-content-server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mozilla/fxa-content-server/merges","archive_url":"https://api.github.com/repos/mozilla/fxa-content-server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mozilla/fxa-content-server/downloads","issues_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues{/number}","pulls_url":"https://api.github.com/repos/mozilla/fxa-content-server/pulls{/number}","milestones_url":"https://api.github.com/repos/mozilla/fxa-content-server/milestones{/number}","notifications_url":"https://api.github.com/repos/mozilla/fxa-content-server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mozilla/fxa-content-server/labels{/name}","releases_url":"https://api.github.com/repos/mozilla/fxa-content-server/releases{/id}","deployments_url":"https://api.github.com/repos/mozilla/fxa-content-server/deployments","created_at":"2013-07-30T23:35:35Z","updated_at":"2016-03-27T04:11:12Z","pushed_at":"2016-03-31T10:59:07Z","git_url":"git://github.com/mozilla/fxa-content-server.git","ssh_url":"git@github.com:mozilla/fxa-content-server.git","clone_url":"https://github.com/mozilla/fxa-content-server.git","svn_url":"https://github.com/mozilla/fxa-content-server","homepage":"","size":15042,"stargazers_count":90,"watchers_count":90,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":56,"mirror_url":null,"open_issues_count":129,"forks":56,"open_issues":129,"watchers":90,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619"},"html":{"href":"https://github.com/mozilla/fxa-content-server/pull/3619"},"issue":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/issues/3619"},"comments":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/issues/3619/comments"},"review_comments":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619/comments"},"review_comment":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/pulls/3619/commits"},"statuses":{"href":"https://api.github.com/repos/mozilla/fxa-content-server/statuses/8e499e41c3c5439ece942f24b67742e04a6e8018"}}}}