Skip to content

Instantly share code, notes, and snippets.

@jcro21
Last active December 14, 2021 03:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcro21/f90a23e81dc4ab70ba000ac4da05f77a to your computer and use it in GitHub Desktop.
Save jcro21/f90a23e81dc4ab70ba000ac4da05f77a to your computer and use it in GitHub Desktop.
gistpad-scratch
<powershell>
$Path = $env:TEMP; $Installer = "chrome_installer.exe"; Invoke-WebRequest "http://dl.google.com/chrome/chrome_installer.exe" -OutFile $Path\$Installer; Start-Process -FilePath $Path\$Installer -Args "/silent /install" -Verb RunAs -Wait; Remove-Item $Path\$Installer

Set-MpPreference -DisableRealtimeMonitoring $true

$NewPassword = ConvertTo-SecureString "TestPassword#001.t" -AsPlainText -Force

Set-LocalUser -Name Administrator -Password $NewPassword

</powershell>

https://portal.edd.ca.gov/WebApp/Login?resource_url=https%3A%2F%2Fportal.edd.ca.gov%2FWebApp%2FHome

{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": ""
    },
    "eventTime": "2021-10-17T16:15:05Z",
    "eventSource": "signin.amazonaws.com",
    "eventName": "ConsoleLogin",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "160.116.230.231",
    "userAgent": "AWSBFF BFFiOS/2.4.7.614 Mobile iOS/14.3 iPhone10,1",
    "requestParameters": null,
    "responseElements": {
        "ConsoleLogin": "Success"
    },
    "additionalEventData": {
        "LoginTo": "https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2&state=hashArgs%23&isauthcode=true",
        "MobileVersion": "No",
        "MFAUsed": "No"
    },
    "eventID": "67063a63-bbbf-49e5-87a2-0e43b72f84e8",
    "readOnly": false,
    "eventType": "AwsConsoleSignIn",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
        "clientProvidedHostHeader": "signin.aws.amazon.com"
    }
},
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": ""
    },
    "eventTime": "2021-10-19T10:41:15Z",
    "eventSource": "signin.amazonaws.com",
    "eventName": "ConsoleLogin",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "107.173.110.124",
    "userAgent": "AWSBFF BFFiOS/2.4.7.614 Mobile iOS/14.3 iPhone10,1",
    "requestParameters": null,
    "responseElements": {
        "ConsoleLogin": "Success"
    },
    "additionalEventData": {
        "LoginTo": "https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2&state=hashArgs%23&isauthcode=true",
        "MobileVersion": "No",
        "MFAUsed": "No"
    },
    "eventID": "6b148c1d-3363-49de-a6f2-2bd19d0073be",
    "readOnly": false,
    "eventType": "AwsConsoleSignIn",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
        "clientProvidedHostHeader": "signin.aws.amazon.com"
    }
},
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": ""
    },
    "eventTime": "2021-11-23T09:08:22Z",
    "eventSource": "signin.amazonaws.com",
    "eventName": "ConsoleLogin",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "168.81.131.240",
    "userAgent": "AWSBFF BFFiOS/2.4.7.614 Mobile iOS/14.3 iPhone10,1",
    "requestParameters": null,
    "responseElements": {
        "ConsoleLogin": "Success"
    },
    "additionalEventData": {
        "LoginTo": "https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2&state=hashArgs%23&isauthcode=true",
        "MobileVersion": "No",
        "MFAUsed": "No"
    },
    "eventID": "1b4b2a95-3455-4090-89bb-57fbdf141ccb",
    "readOnly": false,
    "eventType": "AwsConsoleSignIn",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
        "clientProvidedHostHeader": "signin.aws.amazon.com"
    }
},
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": "ASIAS3RFHA56GZQDURGW",
        "sessionContext": {
            "sessionIssuer": {},
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2021-11-23T09:08:22Z",
                "mfaAuthenticated": "false"
            }
        }
    },
    "eventTime": "2021-11-23T09:08:24Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "CreateKeyPair",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "168.81.131.240",
    "userAgent": "console.ec2.amazonaws.com",
    "requestParameters": {
        "keyName": "testkeyxvlx"
    },
    "responseElements": {
        "requestId": "68b44540-ef41-4901-ba65-55593c82a38c",
        "keyName": "testkeyxvlx",
        "keyFingerprint": "67:a8:2e:31:a3:04:67:fd:80:55:63:1c:f6:f2:45:08:97:a4:1d:a9",
        "keyPairId": "key-064b6954d5d68285a",
        "keyMaterial": "<sensitiveDataRemoved>"
    },
    "requestID": "68b44540-ef41-4901-ba65-55593c82a38c",
    "eventID": "2de3a0a3-8ed7-4fdd-8219-f5bec11fd486",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management"
},
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": "ASIAS3RFHA56GZQDURGW",
        "sessionContext": {
            "sessionIssuer": {},
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2021-11-23T09:08:22Z",
                "mfaAuthenticated": "false"
            }
        }
    },
    "eventTime": "2021-11-23T09:08:26Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "CreateSecurityGroup",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "168.81.131.240",
    "userAgent": "console.ec2.amazonaws.com",
    "requestParameters": {
        "groupName": "testkeyxvlx",
        "groupDescription": "launch-wizard-2",
        "vpcId": "vpc-007e1172e46bca678"
    },
    "responseElements": {
        "requestId": "39fdbd09-0595-45fd-afa8-c6512b75bf1e",
        "_return": true,
        "groupId": "sg-0c9f2c602c6b69af6"
    },
    "requestID": "39fdbd09-0595-45fd-afa8-c6512b75bf1e",
    "eventID": "eb1c7390-fc6e-40df-98df-deadc508cd0e",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management"
},
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "Root",
        "principalId": "196572809084",
        "arn": "arn:aws:iam::196572809084:root",
        "accountId": "196572809084",
        "accessKeyId": "ASIAS3RFHA56GZQDURGW",
        "sessionContext": {
            "sessionIssuer": {},
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2021-11-23T09:08:22Z",
                "mfaAuthenticated": "false"
            }
        }
    },
    "eventTime": "2021-11-23T09:08:27Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "AuthorizeSecurityGroupIngress",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "168.81.131.240",
    "userAgent": "console.ec2.amazonaws.com",
    "requestParameters": {
        "groupId": "sg-0c9f2c602c6b69af6",
        "ipPermissions": {
            "items": [
                {
                    "ipProtocol": "tcp",
                    "fromPort": 3389,
                    "toPort": 3389,
                    "groups": {},
                    "ipRanges": {
                        "items": [
                            {
                                "cidrIp": "0.0.0.0/0"
                            }
                        ]
                    },
                    "ipv6Ranges": {},
                    "prefixListIds": {}
                }
            ]
        }
    },
    "responseElements": {
        "requestId": "dbeb2e03-7f8f-45c6-aef5-4c56d496a621",
        "_return": true,
        "securityGroupRuleSet": {
            "items": [
                {
                    "groupOwnerId": "196572809084",
                    "groupId": "sg-0c9f2c602c6b69af6",
                    "securityGroupRuleId": "sgr-06cf11becb75f2cae",
                    "isEgress": false,
                    "ipProtocol": "tcp",
                    "fromPort": 3389,
                    "toPort": 3389,
                    "cidrIpv4": "0.0.0.0/0"
                }
            ]
        }
    },
    "requestID": "dbeb2e03-7f8f-45c6-aef5-4c56d496a621",
    "eventID": "9386673c-b5fe-4475-9f9e-f39ea84df7fe",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "196572809084",
    "eventCategory": "Management"
}

Proxy app: 911 S5 3.37 website: 911.re Username: OT231

dropbox.com gvc= MjY1NTk1NzYzNDc1MDgzODA3NzU3ODE1NTk5ODYxMDYyMjc3NjYy

sofia.trustx.org

https://file.io/lQjtKT1ttHzp https://file.io/swepGOz1WJbI

If you are keen, got a job the boss wants done concurrent to the ongoing dev that I think would suit you. (unlike last time we spoke about a module this one doesn't depend on the management to get moving 😒 so you could get started tomorrow if you like) tldr: make backend to monitor, parse, store, and retrieve emails Core part of the planned CRM system is centralised communication tracking, and a core part of that is sent/received email integration. Visit a customer's card to see all interaction between $businessUsingStockman and the customer in question, easy to catch up on the relationship with confidence. Sent/Received emails is the part we want to get built now, rest to be done in the future. How this is achieved is largely dealers choice given the following: Firm reqs

  • Process new received mail within 2 minutes of arrival
  • Associate with company (tblCompanyDetails.CompanyIdentifier) automatically (should be a simple match of from address to company contact email address (tblPerson.email)
  • Searchable/filterable on some common fields ie recipient, sender, date, subject
  • Mail data must be immutable ... (this is the real meat of the task right here)
  • Some emails may be sensitive, need a way to prevent for example a standard sales user from seeing mail between CEO and customer Soft reqs
  • ability to reassemble into an email (edited) 12:48 I've already got the gsuite/gmail integration working, extremely basic in the backend though but the main point is that the domain wide delegation stuff is all tested and working 12:49 so the whole thing can be achieved using just the GCP service account, no need for users to give authorisation, no need for any user input or action whatsoever

jcro 12:57 the gmail go lib makes this stuff pretty good to work with 12:59 and it includes subscription/watch methods so the mailbox monitoring should also be a relatively easy thing to achieve 13:00 the big problem to solve is how to store and serve the information

jcro 13:08 my first thought is to store the headers and MIME text part in the database since they'll be small enough to be reasonable and then we can use them to search/filter and importantly to display in a performant manner 13:09 and then store the attachments in a sub-bucket of that company-card's file bucket 13:09 link the two groups of data together via the email message's UUID 13:10 fetch attachments on demand 13:10 has a few minor bonus side effects too (edited) 13:15 anyway I'll stop talking at you, I'm sure you get the idea - we can discuss more if you're interested 👍

s1へ 13:29 reads 13:31 yeah your idea of storing the email content is spot on - that's exactly what popped to mind reading the spec 13:35

  • SLA in terms of processing time is fine
  • company association might require some additional functionality (e.g. if someone emails from their personal account, maybe that should go into some kind of reconciliation queue?)
  • search/filter is easy peasy
  • immutable is fine - i propose two levels: 1) is that it's immutable for everyone except database administrators (i.e. us) via not exposing write mechanisms, 2) is that it's immutable via some kind of hard-to-falsify-after-the-fact log (think blockchain - a string of hashes)
  • sensitive content is obviously subjective, so might also require some kind of queue for confirming they contain no sensitive information (this would be an interface used by people who are allowed to see such information maybe?)

jcro 13:35 schweet, I haven't had a look at whether or not the gcp file buckets are suitable for this kind of profile but I'm sure gcp would have something that suits

s1へ 13:36 not sure what the "reassemble into an email" thing means - is this like a "send response" feature where we retain the email thread in the reply?

jcro 13:36 naw, just that people will want to "see the email" if asked to produce it

s1へ 13:37 oh right, that's fine

jcro 13:37 i.e. if asked to by lawyers

s1へ 13:37 yep, so that's more for audit 13:37 all good

jcro 13:39 (e.g. if someone emails from their personal account, maybe that should go into some kind of reconciliation queue?) if no mail address match found I'm thinking it goes into a 'spam' style collection that purges at 30days of age 13:40 users can go look at that list of mails (showing only those addressed to or from their own email address of course) and click a button on a message to send that message through processing again 13:41 so they could see it didn't attach, go create a contact on the customer card, tell the system to process/re-evaluate that message, and this time it'll attach as expected because it now matches a contact

s1へ 13:42 that'd work

jcro 13:42 that stuff is easy to tack on though 13:43 so the fine user interactions aren't too important as long as we have the structure required

s1へ 13:44 sounds reasonable

jcro 13:44 2) is that it's immutable via some kind of hard-to-falsify-after-the-fact log (think blockchain - a string of hashes) Is this because you want provable immutability? 13:45 Immutability I had in mind was essentially preventing std user actions from changing the data 13:46 most common and obvious desire being: we don't want them to be able to delete emails 13:46 delete it from your mailbox if you like Mr. Andy Mc'Saleserson, it won't save you

s1へ 13:47 yeah, with the goal of changing the risk profile - if there are questions of reliability in terms of provenance, a blockchain-like string of hashes approach would make it very hard to falsify past emails, and it would get harder as time goes by 13:47 right, so it just depends on the risk profile 13:47 if the business wants to protect itself against end users, simply restricting their ability to modify the content is fine

jcro 13:48 yeah the only desire expressed to me was preventing end users from destructive acts (edited)

s1へ 13:48 if the business wants to protect itself against the people running the system (us), we'll need to take some more steps, and give management a way to confirm that specific records haven't been modified 13:49 cool, sounds easy then 13:49 might be worth clarifying though, if it hasn't been explored already internally

jcro 13:49 the reason I reckoned it'd be the meaty part was because that requirement alone means we must take control of the parsing, storing, and querying instead of leaving it up to gmail 13:50 otherwise we could just retrieve message from the users mailbox

s1へ 13:50 oh i'd be storing it locally anyway, just to make sure a gmail outage doesn't take down the company's comms history

jcro 13:50 if the business wants to protect itself against the people running the system (us), we'll need to take some more steps oh they have absolutely no concern about that direction at all

s1へ 13:51 nice, easy then

jcro 13:51 so yeah dodged that one

jcro 13:56 RE the queue type system to allow some pre-filtering of sensitive info: I'm thinking this sort of approach Standard users: Mail is attached and visible by default, with 30 minute window from insertion to rescind the public display flag Manager/sensitive users: Mail is attached and invisible by default, with unlimited window to grant the public display flag

s1へ 13:57 right, so depending on the recipient of the email, we'll mark it as public or not public at the start 13:58 that'd work

jcro 13:58 messages that are attached but invisible could display the To and From and Subject but omit the body 13:58 but that's nonstructural I guess (edited) 14:00 right, so depending on the recipient of the email, we'll mark it as public or not public at the start hmm, yeah a flag for public and a field for a list of users granted specific access 14:02 id: 123 message: { ...message object... } public: false explicitViewers: "AdamA, BarryB, CeciliaC"

s1へ 14:03 how would the user list be populated? a default for each recipient with per-message override or something? (edited)

jcro 14:03 nil by default

s1へ 14:03 makes sense

jcro 14:04 and user who 'owns' the email (To or From them) or someone who has administrative privs can go to that message and "Add view user" 14:04 kinda like sharing on a google doc (edited) 14:06 2 files image.png

image.png

s1へ 14:10 nod

jcro 14:12 I can't really see a way it'd be a factor in this structure but I intend to integrate this into gmail later down the track, in the style of "click a button/icon on the message to change it's visibility/which users have view permission" type stuff 14:12 so maybe we want to record the gmail message UID

s1へ 14:12 is that a gmail thing? or would that be a browser extension or something? 14:12 we can certainly record whatever data is necessary

jcro 14:14 I haven't looked properly but I think you can do it 2 ways, full on gsuite addon which integrates into the gmail interface (surprising amount of agency they give you there), or a "lite" version of an addon (appears in the sidebar and is kinda seperate from the rest of gmail UI)

s1へ 14:14 neat

jcro 14:15 image.png image.png

14:15 the Keep stuff there is the second type

s1へ 14:15 so ballpark (off the record) i want to say two weeks delivery time, $10k budget

jcro 14:16 yupyup

s1へ 14:16 is that roughly aligned with business objectives?

jcro 14:17 can't say, didn't actually give me an expectation there - but my gut feel is that'd be fine 14:17 90% confidence

s1へ 14:17 i'll have to write up a set of completion criteria to make sure everyone knows what they're getting into, which i'll cost into the end price, and which i think will fit into $10k just fine 14:18 but let's keep that a teensy bit flexible for the moment 14:18 feel free to float the number around, but don't hold me to it until i've written that specification and we've made sure it meets all the required objectives

jcro 14:19 Yep, this can be pretty fluid I'd say as well, since it's not a 'sealed and finished product' type thing

s1へ 14:19 i would be very surprised if it went further than $15k without some serious curveballs 14:19 and even that is like, if someone asked for some really complex buisness rules 14:20 (something that hasn't already been mentioned i mean)

jcro 14:21 yeah I don't see any requirements jumping out 14:21 can't imagine what one could even be realistically 14:22 the scope creep with this sorta thing would surely be the user interaction layer

s1へ 14:22 something nebulous like "anyone i've ever talked to should be counted as one of my contacts, except if they mention the n-word"

jcro 14:23 and the aim is to punch out a super basic version of that 14:24 and I'll apply the fiddly coat of paint and dressings like filter/search/permission/sharing/blahblah later when I start designing the CRM properly

s1へ 14:25 yeah - of course i'd try to structure things to make that as easy as possible 14:25 in other news, did david ask you about his "phpbb for business" concept?

jcro 14:25 yeah robust structure is the main focus at this point for sure 14:26 Don't think so? phpbb for business sounds like a terrible idea though

s1へ 14:26 well, i'm paraphrasing

jcro 14:27 is this david banham?

s1へ 14:27 he was basically saying that the slack-only monoculture in some startups is actually stifling to effective communication 14:27 yep

jcro 14:27 ah, haven't opened VS in about a year

s1へ 14:28 i have it as a tab in my slack client, but i only open it when i get a notification heh 14:28 he had kind of a cool thought process around focussing more on discussion threads 14:28 basically slack tried to make that happen, but they fumbled bad on it

jcro 14:28 what's the main premise of the slack-only is bad theory?

s1へ 14:29 basically that the concept of topic permanence is almost void in slack 14:29 if you chat about something important and reach a conclusion, it can be pushed out by shitposting

jcro 14:29 discussion threads in business would actualise as entity-based wouldn't it? 14:30 so like a much evolved version of the comment system in stockman 14:30 topic = business entity

s1へ 14:30 so without judicious use of threading (annoying in slack) or lots of channels (annoying maybe in general?), a real-time chat system has flaws that make it unsuitable for business use past the point of maybe 5 active users 14:30 yeah, something like that

jcro 14:31 yeah I agree with that 14:31 you see enough evidence in devanz, it's just that it doesn't matter much

s1へ 14:31 he has some interesting thoughts on the topic, and i had a good discussion with him about it the other day 14:31 oh yeah but devanz is just 24/7 shitposts 14:31 so it works fine for that

jcro 14:31 I'm pretty interested in this actually

s1へ 14:32 you should ask him about it - you've got the same level of context i do with him 14:32 it sounds like he actually wants to take a stab at it

jcro 14:32 communication and singularity of direction/intent/goals is a problem in this business

s1へ 14:33 i kind of want to think of it as "4chan for business" - i think a lot of the properties of a *chan-style board would translate well to business 14:33 forced thread topic, forced attachment for initial post, bump (thread size) limit 14:33 but i expect he doesn't want to couch it in those terms

jcro 14:34 I would never have thought getting everyone on the same page would be such a difficult and important task, but turns out a bunch of 50 year olds with no tech inclination will passively resist it

s1へ 14:35 they sure as fuck know how to use facebook though 14:35 and that has a similar model

jcro 14:37 hmm, forced attachment places a barrier to discussion

s1へ 14:38 it does - but an attachment in this context could be a client email, or a specific sale, etc

jcro 14:38 which might actually be desirable in some cases, but dampen comms through increased effort cost

s1へ 14:38 a discussion should have a context

jcro 14:39 "Next FY budget discussion" 14:39 entity that doesn't exist yet 14:40 but I'm probably being too narrow sighted on the "attachment" meaning there

s1へ 14:41 the attachment could also be a meme of donald trump on a motorbike 14:41 so you know 14:41 it's fluid

jcro 14:41 I can see the benefits for sure, but since it's 3rd party the lack of integration might be a killer 14:42 fluid triggered

s1へ 14:44 heh 14:44 i told him his biggest hurdle would be SSO 14:44 but i like the concept

jcro 17:04 just got off the phone, all seems good, no new requirements and they're happy to move ahead 17:05 they did have one "can you make it so"

s1へ 17:05 cool, i'll write up a more formal document this weekend, then if we can get it approved early next week we can get cracking

jcro 17:05 "A button or tickbox when you're writing the email so make it public or private"

s1へ 17:06 hrm

jcro 17:06 so if you could just inject some custom code and interface into every email client on every platform 17:06 that'd be great

s1へ 17:06 i guess we could put replies into their own queue 17:06 give them a longer timeout

jcro 17:06 obviously I told them 'no not really'

s1へ 17:06 make sure it's effectively communicated to staff

jcro 17:07 I offered that we could make any email that is BCC'd to $systemAccount be flagged private etc

s1へ 17:07 "if you want your email replies to customers to be private, please log into stockman within $x time of sending them" 17:07 that would work too

jcro 17:07 or include a code in subj or body like [!priv]

s1へ 17:07 oh sure, or even the other way

jcro 17:08 make it a macro or whatever for ease 17:08 they didn't like the idea of having to go into the customer card and toggle the email they just sent

s1へ 17:08 make it private-by-default, and require a tag (or follow-up activity in stockman) for making it "public"

jcro 17:09 ah but then we fall foul of the 'path of least resistance' 17:09 and have no public data 17:09 these slaves secondaries respond to the lash

s1へ 17:10 or an email subject tag - user receives this steel rod gave me internal bleeding, replies with sales: re: this steel rod gave me internal bleeting 17:10 we can definitely shoehorn some magic into the email content

jcro 17:10 hmm 17:11 that'd require outgoing interception 17:11 so relaying through a proxy we build

s1へ 17:11 if we can fetch the inbox we can fetch the outbox, right?

jcro 17:11 moving parts

s1へ 17:11 via gmail?

jcro 17:12 yeah the gmail api subscribe method feeds you every event that occurs if it changes the mailbox state (edited) 17:12 so incoming, outgoing, draft, delete 17:12 etc etc

s1へ 17:12 yeah i figured we'd be keeping any ingoing/outgoing mails

jcro 17:12 but if they write an email in outlook and hit send 17:12 we can't alter the email the customer gets right? 17:12 I assume

s1へ 17:12 no we can't, i don't think 17:13 but as long as it triggers a change in gmail, we can log it 17:13 (and do things based on it)

jcro 17:13 yeah 17:13 oh I've gone down wrong headpath here

s1へ 17:13 oh?

jcro 17:13 How does this identify an email as desired private?

s1へ 17:14 if they put some magic in the email body, subject, or headers, we can react to it

jcro 17:14 ah yeah, that was my original thought

s1へ 17:14 or if they quickly (within $x minutes) log into stockman and change it 17:14 if they forget to put it in the email

jcro 17:14 either a BCC address or a code in subj/body

s1へ 17:14 yeah

jcro 17:15 it's just not really possible to make that user friendly

s1へ 17:15 bcc to secret-cock-story@fagstore.com

jcro 17:15 but that's their problem, if they want it private, they'll do it

s1へ 17:15 yep

jcro 17:15 you won't believe the last picture!

s1へ 17:16 we can hold the email as private for some specified period

jcro 17:16 hmm yeah actually that's a very good idea

s1へ 17:16 release it as public when that period ends if they don't otherwise tell us to retain it

jcro 17:16 just for the outgoings

s1へ 17:16 yeah, like 30m or something

jcro 17:17 push event to stockman, alert modal asks them to give a YES/NO

s1へ 17:17 if you send an email at 170km/h and go "oh fuck" that gives you enough time to pull over and get your laptop out

jcro 17:17 could even go further and if no push event subscriber is present, send an email and extend the grace period to 12 hours 17:17 or 6 working hours, w/e

s1へ 17:18 yeah that'd work

jcro 17:19 trying to imagine if that would be incredibly annoying or not 17:20 I think the avg sales person sends ~50 emails a day

s1へ 17:20 not sure if we keep state of subscribed viewers, but it doesn't sound hard to do

jcro 17:20 well they poll right 17:20 and it's an authenticated request

s1へ 17:20 if we don't have a record of the user having pinged any application server in the last 5 minutes, send them a push notification 17:20 seems easy enough 17:20 yeah

jcro 17:20 so we can just use lastActivity column in tblLogon

s1へ 17:21 something like that

jcro 17:21 no work needed that way 17:21 active in last 10 minutes = he's there 17:21 not as accurate but this ain't a sniper rifle

s1へ 17:21 seems like a reasonable assumption

jcro 17:22 if we don't have a record of the user having pinged any application server in the last 5 minutes, send them a push notification it'd be if we do wouldn't it? 17:22 if no activity then they don't have stockman open, so send an email and give more grace period

s1へ 17:23 oh, right

jcro 17:23 ok so that kinda logic - much work?

s1へ 17:24 nope, sounds fine to me

jcro 17:24 righto cos it's not a hard req that one

s1へ 17:24 mmm 17:24 if it's desired though, it should go into the requirements

jcro 17:24 I'll go find out if a notification/modal/whatever for each sent email is annoying or not

s1へ 17:25 i don't want to disappoint is all

jcro 17:25 yeah of course

s1へ 17:25 if that functionality is required for the business, i'd like to make sure it's not left out

jcro 17:25 I told them that we could do it via a BCC or string code 17:26 and they were happy enough

s1へ 17:26 so if it's important, i'll consider it in writing up the specification

jcro 17:26 I'll give them a ring now

s1へ 17:26 nod

jcro 17:35 oh boy. True to form we have a slight change. Bucking the trend however - it means less work! 17:36 Sandy prefers typing [priv] or something into the email somewhere, so no need for the notification/push event stuff 17:37 furthermore, she doesn't want anyone to have the ability to change a message to private except a couple of select people 17:37 so for the standard sales staff, all public, all of the time

s1へ 17:37 alright, sounds good to me

jcro 17:38 which frankly I think is not going to be popular

s1へ 17:38 2bad 17:38 you want a different environment, get a different job

jcro 17:38 no more talking shit with your customers/suppliers bois

s1へ 17:38 or go back to 1965, fucking boomer

jcro 17:39 and I've seen some emaill chains "check this video out" that are going to come up in meetings...

s1へ 17:39 trump-on-harley.gif

jcro 17:39 this is a famously boys club industry 17:39 without the as much sexism (edited)

s1へ 17:40 where's the sexism if everyone is a boy 17:40 equal footing

jcro 17:40 "the pair on the new receptionist mate phwoar"

s1へ 17:41 "ha ha thanks for this correspondence, unfortunately i have no way to mark it as private" :joy: 1

jcro 17:41 anyways, not our problem, we just fashion the bayonets

s1へ 17:42 mayonez was not designed to be spread with the bayonet, but the bayonet is perfect size for spreading mayonez 17:42 thank stalin 🙏

jcro 17:42 this means we can axe the whole grace period thing for public flag users

s1へ 17:43 yep 17:43 management override only 17:43 does that mean we need a way to alert management? or does that happen out of band?

jcro 17:44 and management want it to be public by default 17:44 and they'll do the code or toggle in stockman for priv 17:44 so essentially no need for a distinction between the two users anymore 17:44 private toggle ability can just be another permission in the existing permission system

s1へ 17:44 "fuck, fuck, sandy, help, i just told the guy at tasco that their receptionist was fuckin 9/10, yeah, yeah, no, yeah no don't worry what 9/10 means, can you just mark it as private"

jcro 17:45 "sure we can fix this Steven ... so what am I out of 10?"

s1へ 17:46 "sandy if you can bump me up $5k next year you're an 11 easy"

jcro 17:46 and then he just jumped out the window, broke 7 bones, crazy

s1へ 17:46 that's just the way the cookie crumbles 17:47 super weird, totally unpredictable

jcro 17:47 https://devanz.slack.com/archives/D53A04Z6Y/p1602744237124600 out of band

s1へ does that mean we need a way to alert management? or does that happen out of band? Direct message | 15 Oct | View conversation

s1へ 17:47 poifect 17:47 so users with that permission will have a way to mark things as private

jcro 17:48 can happen either via code in email, or by toggle in stockman interface for emails in customer card (edited)

s1へ 17:48 and it'll be up to the people without those permissions to get on the horn if they forget the code 17:48 does this apply to a whole thread? or just individual replies?

jcro 17:48 yep 17:48 oooo 17:48 hmm 17:48 I think the whole thread

s1へ 17:48 and is it retroactive?

jcro 17:49 safer

s1へ 17:49 i.e. mark thread private -> whole thread disappears

jcro 17:49 shite, good point retro is tricky

s1へ 17:49 in case a customer says something fucked

jcro 17:49 I reckon theres a good case for the first half of thread being 👍 public and the rest being 😮 not so 17:50 so how much of a bitch is it to private a thread from this email onward

s1へ 17:50 really it'd be more like a specific message forward 17:51 or maybe "the message subsequent to my last reply" forward 17:51 imagine you've got EmployeeA and CustomerA having a chat 17:51 CustomerA says "fukken alice is hot shit hey"

jcro 17:52 if thread == hasSomePriv { for each email in sorted arrray { if email date > emailContainingPrivDate then hideThisCriminalShit()

s1へ 17:52 EmployeeA wants to put the kibosh on that shit 17:53 then wants to reply with "fuck man i know she's asian but she's not instantly a slut"

jcro 17:53 lol

s1へ 17:53 how do we allow the illustrious fagersta employee to retain both his dignity and that of the customer 17:54 i'm probably thinking too hard on this 17:55 maybe if the customer makes bigoted remarks they deserve to be cancelled

jcro 17:55 public announcement that he's "chosen to explore other opportunities" and has "enjoyed his time at fagersta"

s1へ 17:56 "'s incredible journey"

jcro 17:56 the likely case would be a continuation of the discussion at a higher executive level

s1へ 17:56 automatically delete from salesforce 17:56 https://ourincrediblejourney.tumblr.com/ ourincrediblejourney.tumblr.comourincrediblejourney.tumblr.com Our Incredible Journey Putting the ack! in acquihire

jcro 17:57 so for some people the thread ends at n-4 and for some it's at n messages (edited)

s1へ 17:57 right, so again, allow management to choose which messages are private 17:58 nothing to hide, nothing to fear

jcro 17:58 yep, but the feature here is partial threading

s1へ 17:58 that policy has worked for the US government for 70 years

jcro 17:58 as in, first 3 emails are public, subsequent are not (edited)

s1へ 17:58 hrmm right

jcro 17:58 it's for their own good

s1へ 17:58 so customer contact, follow-up, response - public by default 17:59 subsequent messages - private by default, optionally public at management discretion, or at employee discretion within 30m (of each message) (edited)

jcro 18:00 we don't want the kind of people who use obscene language like "mate you guys got fucking slaughtered on the weekend, wooden spoon again!", "I swear our on ballers were a pack of useless cunts" 18:01 meanwhile, I'll have my email address in the whitelist to skip the fuck out of this system 18:01 that's an actual requirement that I didn't think to mention btw 18:02 we don't want every single account in the domain monitored 18:02 otherwise stockman@fagersta.com.au and fagerstasystem@fagersta.com.au will flood everything with spam

s1へ 18:03 wait so does that mean that for each thread, message n>3 with non-management recipient or sender should be public by default? or private by default? or does it not matter? 18:03 assuming that thread with n=1 is customer-related

jcro 18:05 https://devanz.slack.com/archives/D53A04Z6Y/p1602745181141200 yes except for this part "or at employee discretion within 30m (of each message)" - that's what I was saying before we no longer need that 30min part because management have decided that no one except special permission holders can make a message private

s1へ subsequent messages - private by default, optionally public at management discretion, or at employee discretion within 30m (of each message) Direct message | 15 Oct | View conversation

s1へ 18:05 okey dokey

jcro 18:08 if the $privateKeywordString is in email 4 of email chain 1, 2, 3, 4, ..., n then x >= 4 = private (edited)

s1へ 18:09 can we make that string the n-word 18:10 if a fagersta employee wants to make a conversation private, they have to say the same word method man does

jcro 18:10 however let me say - if this is more than 30 minutes effort then I'd say just make the entire email chain private once a $privateKeywordString is included 18:10 including retro 18:10 hahah

s1へ 18:11 "what, you're better than method man? wow you really are a racist"

jcro 18:11 "i solemnly vow I'm up to no good"

s1へ 18:11 https://www.youtube.com/watch?v=WJOl3vWPfbc YouTubeYouTube | UPROXX Video Wu-Tang Clan - Method Man (Uncut)

18:12 but sure, we can define a content/subject/to: trigger 18:12 if you trip that switch, the whole thread becomes private, pending management intervention

jcro 18:13 shweet 18:15 one more minor thing to look out for - I have not confirmed that an email with 2 recipients say bill@fagersta.com.au and ted@fagersta.com.au possesses a common identifier in each recipient's mailbox 18:16 I presume it does, but I haven't yet checked 18:16 if it didn't that'd make filtering duplicates an absolute cock 18:16 but y'know, surely not

s1へ 17:48 hey look, notifications

jcro 17:48 DING

s1へ 17:48 right so i'm pretty comfortable with the description as it is 17:49 so i guess the ball is in my court to write it up and send over a more detailed spec 17:49 i'll slide it by you for review first, so we can work out the details

jcro 17:50 that all sounds fine to me 17:52 my idea of it isn't too detail heavy as far as 'spec' goes 17:53 largely 'need this feature, works or doesn't' (edited) 17:54 so shout out if you start getting bogged down in details, it might be the case that it's not needed 17:55 (just don't want you to spend time writing it up and later think, "damn, rather not have done that") (edited)

s1へ 17:56 nod

jcro 17:59 oh and you might need some info on how to unfuck the environment into workingness so yell out before you intend to jump in and I'll probably save you some temple-rubbing 17:59 did a 4am "looks like I need to move to webpack4 and friends" on friday

s1へ 18:01 i did one of them recently

Core part of the planned CRM system is centralised communication tracking, and a core part of that is sent/received email integration. Visit a customer's card to see all interaction between $businessUsingStockman and the customer in question, easy to catch up on the relationship with confidence. Sent/Received emails is the part we want to get built now, rest to be done in the future.

How this is achieved is largely dealers choice given the following:

Requirements:

  • Process new mail within a minute of arrival
  • Store and retrieve message data including gmail's message UID, sender, recipient, subject, body, and attachments (attachments in GCP file bucket, rest in the Stockman database) - everything we need to reproduce the email days, months, or years after it was sent
  • Associate with company (tblCompanyDetails.CompanyIdentifier) automatically (should be a simple match of from address to company contact email address (tblPerson.email)
  • Searchable/filterable on some common fields ie recipient, sender, date, subject via api endpoint
  • Retrieve a single mail via api endpoint (like /api/v1/emails/) on some common fields ie recipient, sender, date, subject via api endpoint
  • Mail data should be immutable to users. Of primary note the system should be uneffected by users deleting mail.
  • A whitelist of email addresses should be excluded from monitoring, e.g. recruiting & system mailboxes (whitelist is provided and managed by an existing 'Managed List' object)
  • Permissioned users (upper management mostly) should have the ability to flag an email as private. This should be done by including a keyphrase in the email body, and/or by toggling a flag on the email after the fact in Stockman.
  • Private email is only visible to the user who sent/received it by default, that user may optionally grant view permission to one or more other users on a per email basis (this is in essence just a database column with a comma separated list of users)
  • Mail that cannot be automatically matched to a company should still be stored just like the matched mail. (I will create a system to enable users to match them to contacts/companies after the fact)
  • Simple/barebones 'split-pane' UI to view the mail for a given company (i.e. /company-card/12345/emails). The split-pane should on the left display a list of mail with a searchbox, and clicking on a mail item in the list should display the email in the right-side pane. This interface can be pretty bare-minimum as I will come through afterwards and polish it up.

Tools of relevance used:

  • Go for the backend
  • React + Redux for the frontend
  • mssql for the database
  • Google Cloud Platform
  • git, webpack, flow, eslint, prettier, bugsnag

Meeting on transitioning from MYOB to Xero

Two focuses:

  • Changing the way we do Provisioning to include the legitimate books/accounts i.e. MYOB/Xero
  • Migrating fully from MYOB to Xero

Provisioning changes

  • After move to Xero Provisioning movements will be fully visible/taxable etc

Migrating to Xero

  • ALL costs are inserted into Xero
    • Purchase orders
    • Transport orders
    • Work orders
    • Credits
  • Adjustments to $ amounts on transport, work orders, etc must be recorded in Stockman AND Xero
    • Transaction journal tracking ups and downs as they happen, then use that data to create a monthly up/down transaction to an account in Xero
  • When invoicing a sale:
    • Amount added to cost of goods sold does not include that sales total provision amount, it's seperately transacted into a provision actualised account
  • When applying provision to a pack:
    • immediately add to the Xero Stock On Hand figure

next wednesday 3pm

  • Stock on hand (value of stock excluding provision and including value added by transport and processing after purchase)
  • Sales (amount invoiced to customers. One for each branch or just one for all?)
  • Cost of goods sold (purchase cost + transport + processing)
  • Provision on hand (provision amount added to unsold stock)
  • Provision realised (provision amount that has been sold/realised)

Given the above, the following would be a typical sequence from purchase to sale: Stockman PO#1005 raised, purchasing 2 products: Qty=2.5, UnitCost=$3200.00, Product=Stainless Coil, TotalLineCost=$8000.00 Qty=43, UnitCost=$18.95, Product=Stainless Sheet, TotalLineCost=$814.85 Stockman PO#1005 booked in (with quantities matching the PO for simplicity) TAG# 300101 created in Stockman, total cost is $8000.00 TAG# 300102 created in Stockman, total cost is $814.85 Xero "ACCPAY" Invoice# "1005-1" created with 2 line items the same as above. Both line items are allocated to the 'Stock on hand' account. The two new stock items are provisioned In Stockman TAG# 300101 (Stainless Coil) has it's value increased by $200.00 total, going from a total cost/value of $8000.00 to $8200.00 In Stockman TAG# 300102 (Stainless Sheet) has it's value increased by $75.00 total, going from a total cost/value of $814.85 to $889.85 A Xero 'Manual Journal' entry is raised with two lines 'Provision on hand' account: +$275.00 'Provision realised' account: -$275.00 TAG# 300102 is processed (let's say to add plastic coating) on WO#1045 in Stockman. It's total cost/value is increased by $110.00 to $999.85 Xero "ACCPAY" Invoice# "WO1045-1" created with one line item of $110.00 allocated to the 'Stock on hand' account TAG# 300102 is sold/invoiced on DD#55123 in Stockman Xero "ACCREC" Invoice# "DD#55123-1" created with one line item of $1500.00 allocated to the 'Sales' account A Xero 'Manual Journal' entry is raised with the following lines 'Provision on hand' account: -$75.00 'Provision realised' account: +$75.00 'Stock on hand' account: -$924.85 'Cost of goods sold' account: +$924.85 The Xero 'Stock on hand' should then always be equal to Stockman's, where Stockman's is calculated SUM(PackValue - PackProvisioningApplied) for all unsold packs. Or to do it in the other direction Stockman's 'Stock Value' will be equal to Xero's, where Xero's is calculated 'Stock on hand' + 'Provision on hand'

TAG#338220 - STAINLESS SHEET 304 2B FPE 3.00mm x 1500mm x 3000mm - https://stockmanstaging.fagersta.com.au/pack-details/338220 Provisioning value of $53.5369 per unit DD#75562

Xero Accounts

  • Stock on hand
  • Sales
  • Cost of goods sold
  • Provision on hand
  • Provision realised
  • Write-offs
  • Transport
  • Works

TODO

  • Split pack - should also split the transport and processing equivalently, make sure it doesn't just combine/merge it into the base cost
  • Merge pack - The new packs transport and processing columns should be the sum of the 2 parent packs respective columns, and the appliedprovisioning column should be ((pack1.qty_or_wgt * pack1.appliedProvisioning) + (pack2.qty_or_wgt * pack2.appliedProvisioning)) / (pack1.qty_or_wgt + pack2.qty_or_wgt), make sure it doesn't just combine/merge it into the base cost
  • Task queue for all xero objects
  • Task handling for all xero objects

Handheld scanners/computers - Dec 2021

RS35 Series

https://www.cipherlab.com/en/product-276281/Touch-Mobile-Computer-RS35-Series.html Indicative price: $1,500.00

  • Android 10 (GMS)
  • Octa-core 1.8GHz
  • 2 SIM slots and 1 SAM slot
  • Minimum 12 hours battery life (hot-swappable battery while running)
  • WWAN: EDGE/GPRS/GSM: 850/900/1800/1900
  • WLAN: IEEE 802.11 a/b/g/n/ac/d/h/i
  • HF RFID 13.56 MHz frequency
  • Camera: Rear autofocus 13 megapixels with LED flash
  • 5.5" HD 720 (W) x 1440 (H)
  • 165 x 76.8 x 17.9 mm
  • 288 g (with battery)
  • With rubber boot: 1.8 m (6 ft.) multiple drops onto concrete, 6 drops on each side

The RS35 comes with a hot-swap feature that the dead battery can be simply replaced with a fully charged one even without leaving your current applications or switching to suspending mode Has Google Mobile Service (GMS) and seal of Android Enterprise Recommended (AER) which gives you full enjoyment of Google applications and consistent user experiences With one of the most reliable Wi-Fi transmission on the market

Zebra MC2200/MC2700

https://www.zebra.com/gb/en/products/spec-sheets/mobile-computers/handheld/mc2200-mc2700.html Indicative price:

  • MC2200: $1,170.00

  • MC2700: $1,200.00

  • WiFi-only (MC2200) and WiFi/cellular data (MC2700) options

  • 4 in. WVGA (800 x 480)

  • keypad

  • 296 g

  • Qualcomm Snapdragon™ 660 octa-core, 1.8 GHz

  • 2 or 3 GB RAM

  • Multiple 5 ft./1.52 m drop to concrete

  • 500 1.6 ft./0.5 m tumbles

Zebra TC21/TC26

https://www.barcodes.com.au/content/Zebra-tc26-spec-sheet.pdf Indicative price:

  • TC21: $1,500.00

  • TC26: $1,100.00

  • Wi-Fi-only TC21 or the Wi-Fi/cellular TC26

  • 236 g

  • 5.0 in. color HD (1280 x 720)

  • Qualcomm SnapdragonTM 660 octa-core, 1.8 GHz

  • Android 10

  • 4 GB RAM/64 GB Flash memory; 3 GB RAM/32 GB Flash memory; 2 GB RAM/16 GB Flash memory

  • 4 ft./1.2 m drop to concrete

  • 300 tumbles, 1.6 ft./0.5 m

Scotch whiskey

Talisker 18 Year Old - 96% on Dans - 4.5:star: Master of Malt - $159.90

  • Tasting Note by The Chaps at Master of Malt
    • Nose: Quite clean and fresh. There is a mixed fruity sweetness with a spicy character. The peat and smoke rise with notes of perfume and thick oak. Hints of Calvados and a touch of acidity with ground ginger.
    • Palate: Thick, rich and full-bodied. Notes of spicy, peppery oak, espresso beans and wood smoke. A little allspice creeps in, there is a certain zesty character lurking somewhere. The spice builds and builds with utter intent.
    • Finish: Long, with peppery oak.

Auchentoshan 12 Year Old - 96% on Dans - 3.5:star: Master of Malt - $69.90

  • Tasting Note by The Chaps at Master of Malt
    • Nose: A cereal-sweet nose with notes of guava and mango, with a drizzle of honey.
    • Palate: Oaky and sweet palate, with barley sugar, a little passion fruit and vanilla custard too. Perhaps some rose petal jelly in there.
    • Finish: A lengthy, dry and oaky finish with barley sweetness and cocoa powder.

Aberlour 12 Year Old Double Cask - 92% on Dans - 4.5:star: Master of Malt - $94.99

  • Master of Malt reviews
    • Lovely sherry notes, almost no alcohol burn and very fruity! This is a great whisky if you're new to whisky

    • On first opening nothing special, BUT after two weeks flavour dramatically improved, now a fantastic whisky! Highly recommended, rewards patience

    • When I opened the bottle, couple weeks ago, I was not impressed at all. I found it watery and flaverless, just ok for the price actually.
      But now, jesus... It jumped from 70 to 90/100 points ! Still very sweet, but the oak influence has improved massively, adding big fruity notes and a nice spyness.

    • Much better if add just a few drops of water to enhance the pear and buttery sweetness


bunnings

  • digital calipers
  • adjustable feet (industrial grade)
  • plywood
  • marking knife
  • CA glue (superglue) and accelerant
  • pipe clamps
  • barrel hinges
  • foam (spongey padding)

internet (various)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment