Clicks not code and Salesforce Contacts? - salesforce

So I've got a group of users who originally were going to use one custom object and nothing else, and now their team wants a Case system and the whole shebang.
A Case means a Contact, which lives under the account. The Trouble is everything else these users do is driven from that one custom object they use, which isn't tied into the case system. This leaves my users with exactly the problem described here: https://www.buttonclickadmin.com/salesforce-visual-workflow-advanced-flows/
In other words, Lots and lots of extra effort to find an account, check for a contact and then either use it or make a contact.
Now, if I had a primary key (like the email) that I could count on 100% I'd use a flow like that other guy did. But I don't. Lots of the case contacts don't have email or just plain won't give it (or worse use a group email). AFAIK Record Lookups in a flow only pull one record.
I could fix this with some snazzy VisualForce + Apex. I could take the Id from that one custom object the users have and give them a custom search. I could probably tag the Contact with that Id too (I'm trying not to, it's a big org and it's a pain to get permission to update Standard Objects).
Am I missing something? Why are Case Contacts such a pain to create and manage for users? I understand that the workflow of Account -> Contact -> Case helps prevent duplicates, but it's incredibly confusing to tell my users "Don't go to the Case Tab when you want a case, find the account first".

Related

How to provide visibility to users based on field criteria?

How do I provide visibility to records for users based on field criteria?
My demand is: When I have some specific object Files with some specific products the users that contact in this accounts that have this product will see this register of Files. Like:
I create a register on the object File with the field product fill with 'B'';
The account with some specific record type also has the field product filled with 'B' and 'C';
Because of that, the contacts (that are users in the community) present on this account will have access to the object File, because it contains 'B'.
How to reach this solution? I think about a trigger on the object File that will check the accounts that contain the same product, and then, create a sharing rule for that, but I don`t know if is the best option and also, because of the limit of 300. It's that any other way?
Uh, interesting one! You mean real Files (ContentDocument, ContentVersion), not some custom object, right? Files are bit tricky, normally community user would see all files attached to their account + special "Asset" files.
trigger on the object File (...) and then create a sharing rule
Don't think it'll work. Sharing rules are metadata, not data. You'd need a deployment or cheat by making API callout. But also sharing rules don't really work for community, you're supposed to use sharing sets.
You could try making ContentDocumentLinks between the file header (ContentDocument) and Account. And yes, you should be able to do it from trigger. I don't remember if there are limitations like 1 file can be linked at most to X records, this might be tricky. a change of Account's product would potentially mean lots of links to add/remove, maybe move this bit to #future / Queueable.
Alternatively you could just make all files & their folders visible in the community, maybe even for guest user (look into Asset files?). And just show / hide links to their folders based on what's on the account. Bit "security by obscurity" but well, fairly easy to do, adding/removing products wouldn't mean lots of operations. Depends if these files are somewhat sensitive or it's more about guiding the user to what they're interested in.
Ask on https://salesforce.stackexchange.com/ too, somebody can have even better ideas.

Django model structure in my project

I'm creating a text-based browser game and need some advice for django model structure. All the examples are from the same project, therefore I will not repeat the same information assuming you've read all the questions from the top to the bottom.
First question
I have an auth app which contains user profile (Player model), alliance app which holds information about all the unions players join and medals app which represents rewards for both players and alliances.
Both users and alliances can have medals assigned so one of the options is to create a M2M field in Player and Alliance models linking to Medal.
Another option would make medals app usable in any other project of mine. This approach includes the use of generic relations in Medal model which links to either Player or Alliance.
Which solution is more django-like or can I do however I want to?
Second question
There will be tasks for players to accomplish. The scenarios of tasks vary greatly, therefore I need some kind of approach to write unique task progress checking code for each task.
Tasks are held in the database containing information about rewards (which are pretty much the same). Where should I write unique code for each task? Maybe I should add some fields and eval() them later? Then all the information will be held in the DB.
Moreover, tasks demand some tracking, for example, imagine a simple task of going to the manual section (just to make sure the player knows where it is). Then I need to register somewhere whether the player has visited manual page or not. I think about creating another model TaskTrackers in task app. Then another question arises. If I should add OneToOne field from Player to TaskTrackers or vice versa?
To sum up, the main question is whether should I add OneToOneFields/M2M fields to user profile model or add OneToOneFields/Foreigneys from target models to User model? The latter would make my apps more reusable, but the first approach may be more logical.
Waiting for answers.
One your first question, you could do either an M2M to Medal, or use a generic foreign key. You'll end up with a couple of join tables with M2M. With the generic foreign key, you won't have any join tables, but you will have the extra query for the content type. So, you may need to set up both ways and see which is going to impact performance more
On your second question, I might take the approach of using a "Task" model with one or more "Step" models that can be set up as an inline formset. Then you'll need a table like "CompletedPlayerTasks" or something like that, which contains the Player ID, Task ID and Step ID. If a Step ID exists in that table, the task has been completed.
It sounds like you need to be able to create custom fields and forms for the Steps of each Task, which isn't terribly hard to do in Django. There are some off the shelf solutions to do this, but you might need to write your own.
Lastly, I wouldn't name the app that holds your user profiles "auth", which could cause a namespace problem with Django's contrib.auth app. I would name it "profiles", just so it's more obvious what that app does and contains.
Hope that gives you some ideas.

How to structure database tables?

I am planning a database. It will track when a software program has been registered and log the information in the Registered table.
Two questions:
1: where should i log invalid registration attempts. For example if the user enters the wrong registration information or if they try to register but they have used all of their licenses. I want to remember this information but where do i put it?
I was thinking a separate FailiedRegiatration table or in general notifications table. What do you think?
2: Also if a user registers the same computer i want to allow them however i want to document that they reregistered the computer. Where should i store this information?
I was thinking making a DateRegiatered table that is linked to the Refistered table. That way for each successful registration i can keep track if someone reregisteres on the same computer.
Any comments are helpful as i think through this.
Thanks.
If you need to specifically act on failed registrations, or later activate it and make it a successful registration table, store it in a separate table. If you only need to know about it, consider just storing the failure in a log table of some sort.
I think you want a separate table tracking user, and the machine registered on; that way, you know how many registrations a user performed, whether its 1, 2, or 10, etc. Just a pointer table that points to user ID and the registration...
My two cents.
Personally, I prefer to use logs, rather than database tables, to record "events" that are suitable for logging, and your "failed registration" event definitely seems to fall under this category (the "dates of registration" information is more debatable from this point of view).
Of course, that does depend on having a good logging system (with log rotation, etc) and a good log-processing system too -- many hosting providers, for example, may not give you those, though they'll typically let you use a relational DB.
If that's the case (you can't rely on "good logging and log processing", but rather whatever you do need to persist must go s/where in the DB), then one or more "log-like tables" (more or less like you outline) are a kind-of-OK workaround (and it's hard to suggest better ones, especially without enough info about your deployment situation;-).
I think 2 tables would work. One table to track users (eg: id, username, serial, email), and one table to track registrations (id, foreign key to the users table, timestamp, record of success or failure, and some field to id the user's computer).
The second table would be your log table and have entries for successful initial reg, successful re-registration, and failed registration attempts. no?
Depending on how much information on the user's machine you have you can come up with various ways to ID if it is the same machine or not. This is a hard problem though.

Creating a Notifications type feed in GAE Objectify

I'm working on a notification feed for my mobile app and am looking for some help on an issue.
The app is a Twitter/Facebook like app where users can post statuses and other users can like, comment, or subscribe to them.
One thing I want to have in my app is to have a notifications feed where users can see who liked/comment on their post or subscribed to them.
The first part of this system I have figured out, when a user likes/comments/subscribes, a Notification entity will be written to the datastore with details about the event. To show a users Notification's all I have to do is query for all Notification's for that user, sort by date created desc and we have a nice little feed of actions other users took on a specific users account.
The issue I have is what to do when someone unlikes a post, unsubscribes or deletes a comment. Currently, if I were to query for that specific notification, it is possible that nothing would return from the datastore because of eventual consistency. We could imagine someone liking, then immediate unliking a post (b/c who hasn't done that? =P). The query to find that Notification might return null and nothing would get deleted when calling ofy().delete().entity(notification).now(); And now the user has a notification in their feed saying Sally liked his post when in reality she liked then quickly unliked it!
A wrench in this whole system is that I cannot delete by Key<Notification>, because I don't really have a way to know id of the Notification when trying to delete it.
A potential solution I am experimenting with is to not delete any Notifications. Instead I would always write Notification's and simply indicate if the notification was positive or negative. Then in my query to display notifications to a specific user, I could somehow only display the sum-positive Notification's. This would save some money on datastore too because deleting entities is expensive.
There are three main ways I've solved this problem before:
deterministic key
for example
{user-Id}-{post-id}-{liked-by} for likes
{user-id}-{post-id}-{comment-by}-{comment-index} for comments
This will work for most basic use cases for the problem you defined, but you'll have some hairy edge cases to figure out (like managing indexes of comments as they get edited and deleted). This will allow get and delete by key
parallel data structures
The idea here is to create more than one entity at a time in a transaction, but to make sure they have related keys. For example, when someone comments on a feed item, create a Comment entity, then create a CommentedOn entity which has the same ID, but make it have a parent key of the commenter user.
Then, you can make a strongly consistent query for the CommentedOn, and use the same id to do a get by key on the Comment. You can also just store a key, rather than having matching IDs if that's too hard. Having matching IDs in practice was easier each time I did this.
The main limitation of this approach is that you're effectively creating an index yourself out of entities, and while this can give you strongly consistent queries where you need them the throughput limitations of transactional writes can become harder to understand. You also need to manage state changes (like deletes) carefully.
State flags on entities
Assuming the Notification object just shows the user that something happened but links to another entity for the actual data, you could store a state flag (deleted, hidden, private etc) on that entity. Then listing your notifications would be a matter of loading the entities server side and filtering in code (or possibly subsequent filtered queries).
At the end of the day, the complexity of the solution should mirror the complexity of the problem. I would start with approach 3 then migrate to approach 2 when the fuller set of requirements is understood. It is a more robust and flexible approach, but complexity of XG transaction limitations will rear its head - but ultimately a distributed feed like this is a hard problem.
What I ended up doing and what worked for my specific model was that before creating a Notification Entity I would first allocate and ID for it:
// Allocate an ID for a Notification
final Key<Notification> notificationKey = factory().allocateId(Notification.class);
final Long notificationId = notificationKey.getId();
Then when creating my Like or Follow Entity, I would set the property Like.notificationId = notificationId; or Follow.notificationId = notificationId;
Then I would save both Entities.
Later, when I want to delete the Like or Follow I can do so and at the same time get the Id of the Notification, load the Notification by key (which is strongly consistent to do so), and delete it too.
Just another approach that may help someone =D

What are some techniques for stored database keys in URL

I have read that using database keys in a URL is a bad thing to do.
For instance,
My table has 3 fields: ID:int, Title:nvarchar(5), Description:Text
I want to create a page that displays a record. Something like ...
http://server/viewitem.aspx?id=1234
First off, could someone elaborate on why this is a bad thing to do?
and secondly, what are some ways to work around using primary keys in a url?
I think it's perfectly reasonable to use primary keys in the URL.
Some considerations, however:
1) Avoid SQL injection attacks. If you just blindly accept the value of the id URL parameter and pass it into the DB, you are at risk. Make sure you sanitise the input so that it matches whatever format of key you have (e.g. strip any non-numeric characters).
2) SEO. It helps if your URL contains some context about the item (e.g. "big fluffy rabbit" rather than 1234). This helps search engines see that your page is relevant. It can also be useful for your users (I can tell from my browser history which record is which without having to remember a number).
It's not inherently a bad thing to do, but it has some caveats.
Caveat one is that someone can type in different keys and maybe pull up data you didn't want / expect them to get at. You can reduce the chance that this is successful by increasing your key space (for example making ids random 64 bit numbers).
Caveat two is that if you're running a public service and you have competitors they may be able to extract business information from your keys if they are monotonic. Example: create a post today, create a post in a week, compare Ids and you have extracted the rate at which posts are being made.
Caveat three is that it's prone to SQL injection attacks. But you'd never make those mistakes, right?
Using IDs in the URL is not necessarily bad. This site uses it, despite being done by professionals.
How can they be dangerous? When users are allowed to update or delete entries belonging to them, developers implement some sort of authentication, but they often forget to check if the entry really belongs to you. A malicious user could form a URL like "/questions/12345/delete" when he notices that "12345" belongs to you, and it would be deleted.
Programmers should ensure that a database entry with an arbitrary ID really belongs to the current logged-in user before performing such operation.
Sometimes there are strong reasons to avoid exposing IDs in the URL. In such cases, developers often generate random hashes that they store for each entry and use those in the URL. A malicious person tampering in the URL bar would have a hard time guessing a hash that would belong to some other user.
Security and privacy are the main reasons to avoid doing this. Any information that gives away your data structure is more information that a hacker can use to access your database. As mopoke says, you also expose yourself to SQL injection attacks which are fairly common and can be extremely harmful to your database and application. From a privacy standpoint, if you are displaying any information that is sensitive or personal, anybody can just substitute a number to retrieve information and if you have no mechanism for authentication, you could be putting your information at risk. Also, if it's that easy to query your database, you open yourself up to Denial of Service attacks with someone just looping through URL's against your server since they know each one will get a response.
Regardless of the nature of the data, I tend to recommend against sharing anything in the URL that could give away anything about your application's architecture, it seems to me you are just inviting trouble (I feel the same way about hidden fields which aren't really hidden).
To get around it, we usaully encrypt the parameters before passing them. In some cases, the encyrpted URL also includes some form of verification/authentication mechanism so the server can decide if it's ok to process.
Of course every application is different and the level of security you want to implement has to be balanced with functionality, budget, performance, etc. But I don't see anything wrong with being paranoid when it comes to data security.
It's a bit pedantic at times, but you want to use a unique business identifier for things rather than the surrogate key.
It can be as simple as ItemNumber instead of Id.
The Id is a db concern, not a business/user concern.
Using integer primary keys in a URL is a security risk. It is quite easy for someone to post using any number. For example, through normal web application use, the user creates a user record with an ID of 45 (viewitem/id/45). This means the user automatically knows there are 44 other users. And unless you have a correct authorization system in place they can see the other user's information by created their own url (viewitem/id/32).
2a. Use proper authorization.
2b. Use GUIDs for primary keys.
showing the key itself isn't inherently bad because it holds no real meaning, but showing the means to obtain access to an item is bad.
for instance say you had an online store that sold stuff from 2 merchants. Merchant A had items (1, 3, 5, 7) and Merchant B has items (2, 4, 5, 8).
If I am shopping on Merchant A's site and see:
http://server/viewitem.aspx?id=1
I could then try to fiddle with it and type:
http://server/viewitem.aspx?id=2
That might let me access an item that I shouldn't be accessing since I am shopping with Merchant A and not B. In general allowing users to fiddle with stuff like that can lead to security problems. Another brief example is employees that can look at their personal information (id=382) but they type in someone else id to go directly to someone else profile.
Now, having said that.. this is not bad as long as security checks are built into the system that check to make sure people are doing what they are supposed to (ex: not shopping with another merchant or not viewing another employee).
One mechanism is to store information in sessions, but some do not like that. I am not a web programmer so I will not go into that :)
The main thing is to make sure the system is secure. Never trust data that came back from the user.
Everybody seems to be posting the "problems" with using this technique, but I haven't seen any solutions. What are the alternatives. There has to be something in the URL that uniquely defines what you want to display to the user. The only other solution I can think of would be to run your entire site off forms, and have the browser post the value to the server. This is a little trickier to code, as all links need to be form submits. Also, it's only minimally harder for users of the site to put in whatever value they wish. Also this wouldn't allow the user to bookmark anything, which is a major disadvantage.
#John Virgolino mentioned encrypting the entire query string, which could help with this process. However it seems like going a little too far for most applications.
I've been reading about this, looking for a solution, but as #Kibbee says there is no real consensus.
I can think of a few possible solutions:
1) If your table uses integer keys (likely), add a check-sum digit to the identifier. That way, (simple) injection attacks will usually fail. On receiving the request, simply remove the check-sum digit and check that it still matches - if they don't then you know the URL has been tampered with. This method also hides your "rate of growth" (somewhat).
2) When storing the DB record initially, save a "secondary key" or value that you are happy to be a public id. This has to be unique and usually not sequential - examples are a UUID/Guid or a hash (MD5) of the integer ID e.g. http://server/item.aspx?id=AbD3sTGgxkjero (but be careful of characters that are not compatible with http). Nb. the secondary field will need to be indexed, and you will lose benefits of clustering that you get in 1).

Resources